Optimise your website in 5 simple steps

Michał Witkowski
Pragmatists
Published in
8 min readSep 4, 2018

--

Today we’re announcing that starting in July 2018, page speed will be a ranking factor for mobile searches. — Google

TL; DR;

  • head order & resources hints
  • images optimisation
  • fonts optimisation
  • CSS optimisation
  • JavaScript Optimisation

Start

I’ll work on project that is placed on github. You can practice by deploying page on Heroku and mimic my steps. To measure performance I will use webpagetest. In the last article I used Chrome to do same thing. Check it out! Here is how to deploy this app to Heroku. If you will face any issues, drop me a line in comments.

We will start with a very slow webpage and then optimise it, step by step. Below you can see how I set up the WebPagetest and see the first results. Not very impressive isn’t it?

  • Start Render: 13.943 s
  • Speed Index: 19856
  • Load Time: 21.751s
  • Bandwidth: 1.708 KB

Head order & resources hints

In most cases browser is reading your page from top to bottom, so remember to keep the most important statements at the beginning. If you put a massive JS file at the top, users will need to wait until it’s ready before they see page styling.

Order we have:

Correct order:

  • <meta> — metas affecting appearance (charset, vieport)
  • <title> — the title is visible on the top of the browser, it’s crucial for user to see it fast and have sense that something is happening
  • favicon and touch icons — as before, it’s good to see ASAP that something is happening and favicons are supposed to be lightweight
  • Inline CSS and JS — if you have something important that would change first glance apperance, add inline before loading CSS and JS files
  • CSS — the crucial one. This step typically blocks everything else from proccessing, which is why you should put everything else above it

DNS prefetch

DNS prefetch is telling browser to initiate a connection with another host, which it will connect in the near future(fonts from Google’s CDN or other CSS (bootstrap), JS (jQuery)). All this takes place in the background.

Thanks to the previously established connection, the browser will be able to download the file(s) faster.

Browser support

https://caniuse.com/#feat=link-rel-dns-prefetch

Preconnect

Modern browsers try their best to anticipate what connections the site will need before the actual request is made. By initiating early “preconnects”, the browser can set up the necessary sockets ahead of time and eliminate the costly DNS, TCP, and TLS roundtrips from the critical path of the actual request. That said, as smart as modern browsers are, they cannot reliably predict all the preconnect targets for each and every website.

The good news is that we can — finally — help the browser; we can tell the browser which sockets we will need ahead of initiating the actual requests via the new preconnect hint shipping in Firefox 39 and Chrome 46!

By Ilya Grigorik

Browser support

https://caniuse.com/#search=preconnect

Prefetch

If you’re certain that a specific resource like image or js file will be required in the future, then you can ask the browser to download an item and cache it for later. Unlike DNS prefetching, browser is actually requesting and downloading the asset.

https://caniuse.com/#feat=link-rel-prefetch

Results after aplying those changes:

  • Start Render: 8.674s
  • Speed Index: 14409
  • Load Time :19.230s
  • Bandwidth : 1,708 KB

Images

Images are a major topic in web development. I encourage you to dig deeper into this subject. However, it’s supposed to be 5 easy steps. We will cover only images that we have in our slow website.

Let’s start with the background. Look at the screenshot from Chrome Network. Background cat is loaded last, why is that?

Network

CSS background images tend to be loaded and displayed later than images referenced in <img> elements. As a rule, they’re given lower priority by the browser, and the CSS has to finish loading before they can be discovered (making them invisible to the browser preloader).

NCCGroup

There are a few ways to solve it.

Hidden Asset — you can download a background image as an image, so background image will take place normally in the queue.

Preloading — as mentioned earlier. Support is very limitted.

Both solutions surely do help, but don’t solve the problem with responsiveness of the website. Do to so I will use ResponsiveBreakPoints. Of course files should be hosted locally or on a trusted server, so download them and use generator to get code and assets.

Results after aplying those changes:

  • Start Render: 7.398s
  • Speed Index: 7767
  • Load Time : 8.432s
  • Bandwidth : 718 KB

If you want to read more about images.

Fonts

First, look how many fonts you are loading. More than 3? Run to your UX designer and talk it through. I am sure that you can limit yourself to 3 webfonts.
Hosting either self-host or use super quick trusted source. In our example I will self-host. Next trick needs example. Look at the quote below.

Compress

EOT and TTF formats are not compressed by default. Ensure that your servers are configured to apply GZIP compression when delivering these formats.

Unicode range

The unicode-range CSS descriptor sets the specific range of characters to be used from a font defined by @font-face and made available for use on the current page. If the page doesn't use any character in this range, the font is not downloaded; if it uses at least one, the whole font is downloaded.

MDN

Fonts formats

Use most efficient font format for modern browser, yet support the old ones.

Serve WOFF 2.0 variant to browsers that support it.

Serve WOFF variant to the majority of browsers.

Serve TTF variant to old Android (below 4.4) browsers.

Serve EOT variant to old IE (below IE9) browsers.

Developers Google — Optimise Web Fonts

Google fonts

Unfortunetely, Google fonts by default gives us TTF. To convert TTF into WOFF, use everythingfonts or any other formatter you like.

The font display timeline

The font-display descriptor determines how a font face is displayed based on whether and when it is downloaded and ready to use. Read more.

CSS

CSS minification and reduction of unnecessary code

Minification (also minimisation or minimization), in computer programming languages and especially JavaScript, is the process of removing all unnecessary characters from source code without changing its functionality. Wikipedia

Basically, you need to either take your code and paste into CSS minificator or use Webpack/Gulp, or whatever other plugin you use to do so. It’s easy and there are tons of plugins and online tools for it. CSS Minifier.

CSS before JS

We spoke about it previosly, but just as a reminder. The browser is loading your files from top to bottom. Remember to load CSS, which makes your site pretty, before JS, which makes your page interactive.

Above and below the fold

Above the fold, is reffering to HTML elements which will be seen at the first load(can fit into screen resolution). Below the fold is everything that can’t be seen in the first screen.

You, as a developer, know best what is absolutely needed at the very start. Most impartant styles should be loaded in head inline, so the browser doesn’t need to open any special connection before showing the first screen.

Results:

  • Start Render: 7.446s
  • Speed Index: 7748
  • Load Time : 8.432s
  • Bandwidth : 712 KB

JS

Oh.. ok, the last one.

  1. Delete unnecessary JS libraries
  2. Take care of your JS performance and split files
  3. Minify
  4. CND — serve your file wisely
  5. If you use NPM make sure your development dependencies end up in ‘dependencies’ and not ‘devDependencies’.

Those techniques are pretty basic and we talked about them before. If you have any doubts add a comment and I will be happy to help.

Asynchronous vs Deferred

Normal JS execution — parsing of HTML is blocked by JS. It’s stops fetching and waits for JS to fetch and execute.

The async attribute is used to indicate to the browser that the script file can be executed asynchronously. The HTML parser does not need to pause at the point it reaches the script tag to fetch and execute, the execution can happen whenever the script becomes ready after being fetched in parallel with the document parsing.

bitsofco.de

The defer attribute tells the browser to only execute the script file once the HTML document has been fully parsed.

(…)

Like an asynchronously loaded script, the file can be downloaded while the HTML document is still parsing. However, even if the file is fully downloaded long before the document is finished parsing, the script is not executed until the parsing is complete.

bitsofco.de

https://gist.github.com/WitkowskiMichau/7a2d68d78374b2959a4e276f43f92e12

Final Results:

  • Start Render: from 13.943s to 4.865s
  • Speed Index: from 19856 to 7748
  • Load Time: from 21.751s to 7.542s
  • Bandwidth : from 1,708 KB to 704 KB

I am very happy with the results, hope you will be happy with yours. Share what you achived!

If you go into my github — you’ll see my struggle with WOFF. At first, I though it’s a matter of server configuration, but as it came up I just messed up the url. I am not deleting it, so you can see which mistakes I’ve made during preparation for this article.

--

--