Recently we were tidying up the design a little on chromebookcompare.com and trying to make it work better on mobile. While setting up Google Analytics and Google Webmaster Tools I somehow found myself at Google PageSpeed and trying to improve our score there and in Google Chrome’s Audit tab.

Most of the issues resolved around external files. We had quite a few of them (thanks to Google MDL) and the caching and gzip wasn’t working on some (there’s something ironic about a Google project serving up uncompressed files to Chrome). To fix this I decided we should just download the Google Material Design Lite files locally (they don’t change, they’re versioned). CloudFlare lets me control the caching (and enables gzip) on these better than we were getting from Google. But, this meant more files being served from our domain and not bundling them together seemed a bit silly.

The site is hosted free using GitHub Pages (run through CloudFlare to get free HTTPS). We have a small C# app which rips data from the public spreadsheet and spits it out into Jekyll-formatted files for display but otherwis it’s entirely static. CloudFlare is already minifying the content (though in this case, this third party code is already pre-minified) so I just wanted the simplest possible way to bundle all the scripts together in one file that didn’t not require us to run any scripts whenever we changed a file (sometimes we tweak things directly through the GitHub web app on Chromebooks where it’s more coplicated to run scripts and push to GitHub).

Turned out, I already had the solution on this blog. My Google Analytics script is included using Jekyll includes like this:

{% include analytics.htm %}

So I thought I’d give it a try with JavaScript. I created a file named bundle.js inside my s/js folder and added the following:

{% include material.min.js %}
{% include jquery-1.11.1.min.js %}
{% include jquery.tablesorter.min.js %}
{% include jquery.tablesorter.widgets.js %}

I pushed to GitHub and navigated to /s/js/bundle.js in my browser. It came through completely untransformed. Doh.

I did some digging around to try and understand why this wouldn’t work and discovered (or rather re-remembered) that you need YAML front-matter for a page to be transformed in Jekyll. So I tried again:

---
---
{% include material.min.js %}
{% include jquery-1.11.1.min.js %}
{% include jquery.tablesorter.min.js %}
{% include jquery.tablesorter.widgets.js %}

After much refreshing, nothing changed. I was about to give up when I noticed an email from GitHub:

The page build failed with the following error:

A file was included in s/js/bundle.js that is a symlink or does not exist in your _includes directory. For more information, see > https://help.github.com/articles/page-build-failed-file-is-a-symlink.

Whoops! Includes normally live in _includes so I need to use include_relative:

---
---
{% include_relative material.min.js %}
{% include_relative jquery-1.11.1.min.js %}
{% include_relative jquery.tablesorter.min.js %}
{% include_relative jquery.tablesorter.widgets.js %}

After pushing this, everything came through as expected. Now all these files are combined into one file and CloudFlare is minifying them. One request to the same domain as the website is much better than four requests that include an additional uncommon domain.

Via CloudFlare, this bundle is set to cache in browsers for one month. This makes the site nice and fast but will also impact the ability to make changes. For this reason our own JavaScript (/js/main.js) is neither included in this bundle nor in the /s/ folder (anything in /s/ gets the 1-month-cache header).

There’s still lots of room for improvement (like the CSS) but it’s a good start and chromebookcompare.com seems to load very quickly already!