Performance notes, May 2017
“Added @dracos’s traintimes site to my phone home screen – it is faster than any of my apps” – @jukesie, Twitter
On Twitter last week, Bruce Lawson asked people to write up their performance optimisations. I’ve had some bits of time to make some improvements to traintimes.org.uk, and so here is a short essay/notes (I don’t get much free time at present for various small-person-shaped reasons) on how this site is currently seven times quicker than the official site on a mobile:
(WebPageTest, Manchester UK, Chrome, emulated Motorola G gen 4, slow 3G)
The server now runs nginx with HTTP/2
activated for those browsers that support it, which e.g. allows requests to be
concatenation. This was as straightforward as making sure I had a recent
enough version of nginx/OpenSSL (I use the packages from
DotDeb), and adding
http2 to the listen line.
(Okay, you also have to make sure the server is SSL, but I had already done
that for the service worker and geolocation; thanks to
Let’s Encrypt and StartSSL
I’ll include a full breakdown at the end, but suffice it to say that Google’s Lighthouse tool, which audits web pages for performance, installability and more, and on which traintimes.org.uk scores 100/100, says:
Avoids enormous network payloads: Total size was 9 KB (target: 1,600 KB) — Lighthouse
With all the above, the site scores 100 in Google PageSpeed Insights, which is a very useful tool for this area of web development. (If you pick a results page, the mobile score can be a tiny bit less due to the time taken to get the results.)
Please do not leave baggage unattended
I was using jQuery on traintimes.org.uk. To give you an idea of the age of this site, it was jQuery 1.3.2. Actually, that doesn’t give you an idea, because jQuery 1.3.2 was released in 2009, this domain has been running since 2004, and my original live departure boards (with an image map) went live in December 2001, meaning parts of this code can drive a moped and get married this year.
But I digress. As the lovely jQuery file size page shows, jQuery 1.3.2 is 19.2KB in size, gzipped. Did I really need all that for the few bits and bobs I was using on the site?
core.js is my “jQuery replacement”,
as it were. I kept a jQuery-like feel, with functions like
$.getJSON, and by adding functions such as
closest to Element’s prototype. Perhaps I could have restructured
the HTML to reduce these, but this seemed easier :) I got a tiny domready from ded. I think in the end it is
quite cute and readable.
The hardest actual change was replacing all my jQuery
hide('fast')s with CSS transitions. I
could have just dropped the sliding up/down, but I wanted to keep it if
possible and in the end succeeded by adding a transition on max-height. This
slightly annoyingly only works if you have a fixed height for the block, rather
is not available, defaulting to visible – something I wish I could say was true of all sites.
Going off the rails
- It turns
caches.match()into a proper Promise, rathern than something that resolves with undefined upon no match;
- For the front page, it uses the “cache and fetch” mechanism, returning the page from the cache if present, but always updating from the server at the same time;
- For any other HTML pages, it will fetch (we want up-to-date timetable responses!), then cache the response; if the request fails (e.g. we’re offline) it will see if the page is in the cache and display it if so, otherwise display an offline page;
- For non-HTML requests, it will look in the cache first, and only fetch if it can’t find it in there;
- The offline page will display a list of the cached pages you have stored (so you can hopefully get back to the times you’re after even when underground in a cutting sat outside New Street).
Service workers can do background syncing, push notifications, and more, but
you don’t have to use all the whizz bang stuff to do something useful. Also,
as they are progressive and only work in modern browsers, you can use new
=> arrow functions.
The buffet car
Here are my current transfer sizes:
“it’s so lightweight now, it’s quicker to use than actually looking at the announcement boards in a larger station.” – @gwire, Twitter
— Matthew, @dracos