So recently I changed my website, and I wanted to optimize everything I could, mostly for fun. I've read and watched quite a lot of stuff about it, and it was a good way to start practicing.
Measuring
The first step when optimizing anything is to measure. For this, I'll be using page speed insights from Google and web page test. I'll also focus on mobile, that's where one gets more bangs for their bucks. And a really fast mobile website will (almost?) always translate to a fast desktop website.
Step 0
First version of the website online, with absolutely no consideration about speed.
Mobile:
I got a terrible score for user experience because there wasn't even a proper viewport setup. The fix
<meta name="viewport" content="width=device-width" initial-scale="1">
And make my site responsive also. The result: Much better.
Now let's improve the speed.
Minifying & compressing
After that, I added a minification steps:
- Using jade templates, the output is already minified html.
- I'm using gulp as a build tool. The plugin gulp-minify-css took care of minification
- No scripts (yet)
I also enabled gzip
compression. This is supported by all browsers (including linx, curl, and down to IE5). There is just no reason not to use it.
Optimizing images
I used gulp-imagemin to optimize the few images I'm using. It's really easy to setup and can save off quite a few kB.
Caching
In the same step, I also added some caching mechanisms:
- Added an Etag header. This way, if an asset hasn't changed between two requests, only the headers will be transmitted, with a response of
304
, and no body. There is nothing faster than a non transmitted bit. - Leverage http caching. By adding the proper header:
Cache-Control: "max-age=432000"
This number is in seconds, and means the browser can re-use the response for the next five days.
Result We're getting closer. It's already very good, and it would be enough in most cases, but I wanted to go even further.
Eliminate render-blocking css
The last step is to inline the css for above-the-fold content. This way, the browser doesn't have to wait to receive the css file before displaying something. For this task, I used a tool called critical. It takes as an input an html page and a viewport size, and output the css rules used to render the page within the viewport. Internally, it uses phantomJS, so it also works with injected scripts and stylesheets. Although it's experimental, it works very well.
In my case, I had a bit of extra work to do because I was using jade, so I didn't have a ready to use html file, and I couldn't directly inline the critical css (the tool can also directly inline critical css).
Anyway, after this last step, here's the result:
Yeah!
98 !== 100
PageSpeed insights keeps bugging me about how I do not leverage browser cache: Which contradicts what I see using the devtools of firefox or chromium. I'll keep digging a bit but I'm satisfied for the moment.
What's next?
Next, I'll have some fun optimizing TLS and nginx settings so I can establish the https connection in one RTT (that's the goal at least).