Reputation: 1220
For desktop, I have a site with a decent page speed score (currently, 96): https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fwww.usstoragecenters.com%2Fstorage-units%2Fca%2Falhambra%2F2500-w-hellman-ave&tab=desktop
I'm trying to improve the score (mostly for mobile), but I've somehow made it worse (currently, 69 on desktop): https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fstage.usstoragecenters.com%2Fstorage-units%2Fca%2Falhambra%2F2500-w-hellman-ave%3Fplain%3Dtrue&tab=mobile
While converting the site from Angular (the first link) to plain JavaScript (second link), I've managed to lower the desktop Google PageSpeed Insights score from 96 to 69.
I've massive reduced the amount of JavaScript and other resources (2MB on prod vs 500KB on stage).
Looking through the numbers, the thing that stands out to me is that prod has an FCP (First Contentful Paint) of 0.7 seconds, while stage has an FCP of 2.0 seconds. This seems weird to me since stage should be much faster, but is apparently much slower.
Looking at the mobile timeline of thumbnails (desktop is a bit hard to see), it appears as if stage renders the first "full content" much faster:
I highlighted the ones that visually look "complete" to me (stage is on top, prod is on bottom).
Here are some screenshots so you can see what I do (PageSpeed Insights differs fairly significantly each time it's run).
Here is stage:
And here is production:
Here are the main things I did when trying to improve the score:
Those changes should have improved the score.
Do you have any ideas of why, despite my best efforts, the PageSpeed score tanked?
Upvotes: 0
Views: 10431
Reputation: 1220
So I figured out the issue. PageSpeed Insights is drunk.
Well, it's unreliable anyway. I was able to dramatically improve the score by simply removing the server pushing of the JavaScript files (less than 20KB of them).
This is weird because the page actually seems to take longer to display. However, Google PageSpeed Insights thinks it's displaying sooner, and so it improves the score.
One time I tried, the mobile score went up to 99:
I tried again and got a more reasonable 82:
And on desktop, the score went up to 98:
The interesting thing about the mobile screenshot showing 99 is that you can see in the timeline thumbnails that the image for the slideshow at the top of the page hasn't loaded yet. So it seems like a case of Google PSI prematurely deciding that the page has "finished loading", even though it hasn't finished.
It's almost like if you delay certain things long enough, Google will ignore them. In other words, the slower the page is, the better the score they will give you. Which is of course backwards.
In any event, this might be one of those things where I'll go with the slightly less optimal approach in order to achieve a higher score. There may also be a middle ground I can explore (e.g., have the first JavaScript file inject link rel=preload tags in order to load the rest of the JavaScript files immediately rather than wait for the full chain of modules to resolve).
If somebody can come up with a more satisfactory explanation, I'll mark that as the answer. Otherwise, I may end up marking this one as the answer.
EDIT: Here's the middle ground approach I went with that seems to be working. First, I load a JavaScript file called preload.js
that is included like this:
<script src="/preload.js" defer></script>
This is the content of the preload.js
file:
// Optimization to preload all the JavaScript modules. We don't want to server push or preload them
// too soon, as that negatively impacts the Google PageSpeed Insights score (which is odd, but true).
// Instead, we start to load them once this file loads.
let paths = window.preloadJavaScriptPaths || [],
body = document.querySelector('body'),
element;
paths.forEach(path => {
element = document.createElement('link');
element.setAttribute('rel', 'preload');
element.setAttribute('as', 'script');
element.setAttribute('crossorigin', 'anonymous');
element.setAttribute('href', path);
body.appendChild(element);
});
The backend creates a variable on the window object called preloadJavaScriptPaths
. It is just an array of strings (each string being a path to a JavaScript file, such as /app.js
).
The page still loads pretty fast and the score is PSI score is still good (80 mobile, 97 desktop):
Upvotes: 2
Reputation: 24825
You have done a lot of things correctly, but your score is suffering because of First Meaningful Paint
and First Contentful Paint
Looking at the load order etc. I have noticed that your main HTML file has actually increased in size by 33% from 60kb to 81.6kb.
That is your first indicator of where things are going wrong as you must load all HTML before the browser can even begin to think about rendering.
The next issue is that Lighthouse (the engine behind PSI) is showing you that you don't have render blocking content but I don't think the method is perfect in showing what is blocking render.
Your site still needs the SVG logo
and icomoon
files to render everything above the fold.
On the main site these are loaded early, on the staging site they are deferred and start loading much later, delaying your first Contentful paint
etc.
There may be other things but those are a couple I found with a quick glance.
HTML size
- maybe externalise some of the JSON
etc. you have inlined as there is a lot there, lazy load it in instead (suggestion only, haven't explored whether feasible for you)
SVG Logo
- simple to fix, grab the actual text that makes up the logo and inline it instead of using an external resource.
icomoon
- not quite as easy to fix but swap all your icons for inline SVGs
.
Bonus - by changing your icons from fonts to SVG
you help with accessibility for people who have their own style sheets that override fonts (as fonts for icons get over-ridden and make no sense).
Bonus 2 - One less request!
If anyone comes across problems like this you need to do the following to work out what is going on.
Open Developer Tools and go to network tab first.
Set the options to 'Disable Cache - true' and 'Slow 3G' in the dropdown box.
Load each version of the site and compare the waterfall.
Normally you can spot changes in load order and start investigating them - the 'game' is to find items that appear above the fold and try and remove them, defer them or inline them as you have with some of your CSS.
Next thing is to learn to use the Coverage and Rendering tabs as they very quickly point you to problems.
Finally learn how to use the performance tab and understand the trace it produces.
You may already know how to use the above, but if not learn them they will let you find all of your problems quickly.
Upvotes: 2
Reputation: 1766
I'd recommended you to look into the different between how 3rd-party scripts are included between your Prod
and Staging
environment.
Most of the time when I have problem with pagespeed, it's 3rd-party script that cause the tank. YMMV, though.
Just some pointer to start, as I compared the stat between the two, I noticed that this particular Wistia script works quite differently, maybe not the the problem with the script itself, but the way it's embedded are different or something.
On Prod
On Staging
Upvotes: 2