After I made the changes to my site described in Part 1 of this series of articles (Updating An Old Web Site To HTML5 - Part 1) most of the main warnings from Google Analytics went away, and the site settled down and seemed to be performing better in its new HTML5 form.
Then I received an email from Google telling me that my site was to have "Mobile First" indexing enabled, so that its indexing depended on how it rendered for Google's "Googlebot Smartphone" spider. Another change was that indexing would take the site's performance into account as well, with slower sites dropping down the rankings.
I waited until a few weeks after the change date to let the Analytics pick up the latest speed and HTML suggestions, and took another look to see what improvements I could make.
In the time since I last seriously looked at the suggested improvements, Google has started using a different analysis tool, Lighthouse, so the reports for pages look slightly different. There are also some errors displayed in Google Search Console's Mobile Usability Report, but these are specific to several pages, rather than site-wide, so I'll cover those in another article. At this stage I was just looking to make the biggest improvement for the least effort so that, hopefully, my site didn't drop too far in Google's rankings.
Google Analytics| PageSpeed Insights | Opportunities
Several common "Opportunities" were listed for most of the pages:
Eliminate render-blocking resources
"Resources are blocking the first paint of your page. Consider delivering critical JS/CSS inline and deferring all non-critical JS/styles"
Expanding this shows three CSS files that are blocking the initial drawing of the page. One is served from Google, and is used for advertising, so I'd rather not change it. The other two though are the minimized CSS file for my page, and one for third party "Cookie Consent" script.
Looking at the licence for that other component, they seem fine with alterations being made to their code, so I copied the CSS to my local drive. I placed it in a directory from the base directory of the website in the format:
thirdparty/cookieconsent/<version>/
Moving the remote CSS file to the web server avoids a call to the DNS and CMS serving it, and allows it to be cached on the user's browser.
While I was doing that, I moved my own CSS file into a separate directory from the root. Previously all of the references to it were made using relative paths, so I changed all of those to absolute paths. This might save the server a little time but I haven't actually checked the timing on it. It's certainly a pain to debug locally, because I'd need to add a CSS directory at the root of the disk containing my site files, so I may change it back to a relative path at some time.
All CSS files on the server are minimized to reduce their load time, and now the third party CSS comes under my local caching rules, described below.
Each page's links to the CSS files are now:
<link rel="stylesheet" type="text/css" href="/css/2019.1/historicmedway.min.css" media="screen">
<link rel="stylesheet" type="text/css" href="/css/2019.1/historicmedway.print.min.css" media="print">
<link rel="stylesheet" type="text/css" href="/thirdparty/cookieconsent/3.1.0/cookieconsent.min.css" />
The media field ensures only the CSS file for the current display media is render-blocking. The version numbers ("2019.1") allow an extended cache duration to be specified, but still allow clients to detect changes in style. The section below, "Serve static assets with an efficient cache policy", describes this in more detail.
There was also a minimized JavaScript file listed as render-blocking, but this was loaded at the end of the page and its contents were called in the onload
event.
Marking the <script>
tag that imported it as async
was enough to stop it blocking anything.
Serve images in next-gen formats
My site uses a mixture of JPEG and PNG images, depending of the subject of the image. This warning tells me I should convert them to a "next-gen" format. As I would only save 0.15s on the page, I decided to look into the formats a little more. I got these details from the pages Google links to to describe the formats:
JPEG 2000: Supported only by Safari and iOS Safari, giving support to around 13% of users.
JPEG XR: Supported only IE 9+, Edge and IE Mobile, giving support to around 5% of users.
WebP: Supported by more browsers than the JPEG formats, currently around 73% os users.
Looking through these figures, nothing is compatible with anywhere near all of the available browsers, although Google's own WebP is quite well supported. The most important thing though is the quality of the images on the web page, and initial reviews indicate that conversion may not be worth it. This is a change I didn't make, but will keep an eye on.
Diagnostics
There are several items flagged as between average and slow performance, so I decided to start with the simplest to fix.
Serve static assets with an efficient cache policy
Google seems to feel that items should be cached for longer than I was caching them. I updated the caching for CSS, JavaScript and the GIF files I use sometimes to six months by changing the .htaccess
file cache setion to:
# Enable expiration control
ExpiresActive On
# Default expiration: 1 hour after request
# ExpiresDefault "now plus 2 hours"
ExpiresByType text/html "access plus 1 day"
ExpiresByType image/gif "access plus 6 months"
ExpiresByType image/jpeg "access plus 4 weeks"
ExpiresByType image/png "access plus 4 weeks"
ExpiresByType text/css "access plus 6 months"
ExpiresByType text/javascript "access plus 6 months"
ExpiresByType application/xml "access plus 1 week"
ExpiresByType application/xhtml+xml "access plus 1 week"
ExpiresByType application/rss+xml "access plus 1 hour"
ExpiresByType application/javascript "access plus 6 months"
ExpiresByType application/x-javascript "access plus 6 months"
ExpiresByType image/ico "access plus 1 week"
ExpiresByType application/vnd.ms-fontobject "access plus 1 week"
ExpiresByType application/x-font-ttf "access plus 4 weeks"
ExpiresByType application/x-font-woff "access plus 4 weeks"
ExpiresByType application/font-woff "access plus 4 weeks"
ExpiresByType application/font-woff2 "access plus 4 weeks"
ExpiresByType font/opentype "access plus 4 weeks"
ExpiresByType font/woff2 "access plus 4 weeks"
Handling File Changes With Long Cache Durations
If you set a cache duration of six months for a file, the user's browser won't check it for updates until that period has expired. This saves a lot of time and unnecessary data transfer, which is great, but means that if you change the contents of the file on the server, nobody who has the cached version will download the new version until their cache entry expires. This is less great.
For example, the .htaccess
file above sets the expiry of CSS files to 6 months after the last time the user accessed them. This means that you'd have to leave a gap of six months between site accesses before a new version of the CSS file was downloaded. In theory if you keep revisiting a page, the CSS file will NEVER expire from the cache.
To work around this you need to change the URL of the file, because that is how browsers index cached files. For example the URL for the CSS file is currently set to:
href="/css/2019.1/historicmedway.min.css"
This will be cached and kept possibly permanently. When I make a change to the CSS file, all I need to do is make ANY change to the URL such as:
href="/css/2019.2/historicmedway.min.css"
and this forces clients to download the new file version immediately. The old version of the file, with its original URL, is no longer used and just expires from the cache unless it's cleared out beforehand.
So Far, So Good
Although these changes have improved my site's performance, especially for users with desktop machines, it's still far from perfect; in fact a few of the pages' mobile performance figures are pretty feeble. I think I could improve things a lot more, but it will take quite a lot of effort so it's being added to my list of "things I'm going to do when I get the chance". As my site is just a hobby rather than a money-making venture though, the improving it will be a gradual process, with the most serious inefficiencies getting fixed first. At the moment, that means the next thing I'll be looking at is doing some responsive page design and varying the image resolution to fit the screen size...