How I made this blog fast with Middleman and NGINX
TL;DR; Static pages and caching.
A blog such as this one is so simple that I couldn’t imagine hosting anything other than static pages. I’m using Middleman for this, a powerful static site generator written in ruby. It gives you access to things like sprockets as well as extensions like middleman-blog making it really easy to get started if you’re familiar with the Rails stack.
Toolbox
I used the following tools because they not only find the problems, but provide suggestions on how to fix them.
First and foremost, I used the PageSpeed Insights extension for Google Chrome and Firefox. Note that they also provide an online version (bonus: the results that are optimized to reflect performance across all devices).
I also turned to http://www.webpagetest.org/ for a detailed overview (including timelines). I found a few things that I would’ve otherwise ignored.
HTTP Compression
Compressing your site will especially be important for users with slower connections. Less time downloading bytes from your server == more time on page.
I’m using NGINX to serve my site, so let’s tell it that I want HTML, CSS and JavaScript to be served compressed (HTML is always compressed).
gzip on;
gzip_types text/html text/css text/javascript;
There are many other options to optimize HTTP compression, see the ngx_http_gzip_module documentation for those.
Asset minification
Using asset minification will ensure that everyone will get the smallest version of your assets possible. This mostly helps for browsers that doesn’t support HTTP compressions but some claims have been made that it might help compilation/parsing time as well.
It is not turned on by default in Middleman. Add this to your config.rb
:
configure :build do
activate :minify_css
activate :minify_js
end
Browser caching
By taking advantage of browser caching, you can speed up subsequent page loads of your site by instructing browsers that your assets will not expire for a long time. The next time you request them, the browser will load them from local disk instead of over the network. One drawback to this is that a users will continue viewing the cached version even if the expiry date changes and a common solution is to generate a unique file name on every deploy, also referred to as fingerprinting.
As usual, Middleman makes this extremely easy and all you have to do is add the following to your config.rb
.
activate :asset_hash
Note: It’s important to make sure that your assets are all linked using the helper methods like javascript_include_tag
, stylesheet_link_tag
and image_tag
And last but not least, don’t forget to actually configure your web server to set far Expires or Cache-Control headers. This is what I used for nginx:
location ~* \.(ico|css|js|gif|jp?g|png) {
expires max;
break;
}
Conclusion
Sadly, I don’t have much to say and I wish I could finish with some numbers. The site is so small at this stage that any measurements are negligible. On the bright side, I’m pretty confident that my blog will be able to sustain a decent amount of traffic over time without having to be involved.
This is also a really good case against premature optization, something I tend to avoid. In this case, it was about learning and gaining experience, and I’m happy that I got to do it.