Improving Site Speeds and Loading Times for Better SEO Rankings
Across the internet today, we can find websites with many different types of features: sliders, videos, images, animations, and more that make them attractive to end users. However, all of these features can have a negative impact on one major factor: performance.
But wait, why should I care?
According to DoubleClick by Google, 53% of mobile site visits were abandoned if a page took longer than 3 seconds to load. Also, it was found that sites loading within 5 seconds had 35% lower bounce rates, 70% longer sessions, and 25% higher ad viewability than sites taking nearly four times longer at 19 seconds.
The performance impact can be measured in revenue too. DoubleClick found publishers whose sites loaded within five seconds earned up to twice as much ad revenue as sites loading within 19 seconds.
So you should care, and a lot. Performance can be the one thing that is making users ignore your website. It plays a major role when it comes to retaining users, user experience, and revenue. It also affects Google Rankings. That means performance is taken into account by Google when positioning your website in the search results higher (or lower) than your competitors.
So, how can we improve it?
Removing Render and Parsing Blocking Resources
A browser’s rendering engine is in charge of displaying what you see on the screen. In order to accomplish this, it has to parse HTML and create a DOM tree with all the existing HTML elements, render tree construction combining CSS attributes and the DOM tree, figure out each element’s position (layout process), and then paint the page.
When rendering a page, the rendering engine considers CSS as render blocking resources and scripts as render and parsing blocking resources.
Loading your website resources at the right time is essential to improving your website performance. If you load resources that avoid blocking parsing and rendering, your site will display much faster and the lesser critical content can be loaded in the background while the user interacts with the page. There are several ways to do this:
Using media print and onload=’this.media=’all’ to load non critical CSS (or loadCSS as an alternative)
Loading CSS with media type ‘print’ will tell the browser that the resource is not important because the media type doesn't match the current environment (screen), and will load the stylesheet asynchronously without blocking page rendering.
<link rel="stylesheet” href="style.css" media=”print” onload=”this.media=’all’”>
loadCSS is a popular library that also makes this possible.
<head> <script id="loadcss"> // load a CSS file just before the script element containing this code loadCSS( "path/to/mystylesheet.css", document.getElementById("loadcss") ); </script> </head>
We also can combine this with ‘rel=preload’ (in supported browsers) if we want non critical CSS to be loaded as soon as possible.
<link rel="preload" href="style.css" as="style">
This approach has a major downfall if applied to all CSS on the page: the browser will show a Flash of Unstyled Content (FOUC) before loading the CSS. This means that some essential CSS needs to block page rendering in order for the page to be displayed with its proper, critical styles. But asynchronously loading the remaining styles is a must for improving performance.
Async is a boolean attribute that you can place in a script tag that allows the browser to load the script in the background while it keeps parsing the HTML, and then execute the script as soon as it is loaded. This blocks the parsing if it happens before the browser finishes parsing. Async scripts are executed in random order as they become available.
Defer is also a boolean attribute that you can place in a script tag that allows the browser to load the script in the background while it keeps parsing the HTML. It then executes the script after the parsing is done. It’s similar to placing the script at the bottom of the page, the only difference being that it’s loaded in parallel while the HTML is parsing content. It also allows you to execute all deferred scripts in the order in which they appear on the document.
Note that both of these attributes are only useful if the scripts are declared in the header, otherwise they won’t do anything.
Comparing both attributes, async may block html parsing but defer guarantees not to. Neither of them guarantee anything on blocking rendering (however that can be done with the onLoad event).
Furthermore, their biggest difference is the execution order. Async scripts are executed in a random order as they become available, while deferred scripts are executed in the order of their appearance.
I recommend to use async loading in third party scripts where the loading order isn’t important (i.e. Google global site tag) and defer loading for scripts that need the whole DOM loaded and/or their relative execution order is important.
Comparing script loading performance, we obtain these results:
These techniques (along with image lazy loading which is a critical performance improvement that we will comment on in a future post) were implemented on our site (https://kzsoftworks.com) in order to improve its performance.
For comparison, the performance of the site’s old and new versions was measured locally using Lighthouse version 6. In the results shown below, we see a clear improvement in performance with the first contentful paint rendering almost four times faster in the newer version and the largest contentful paint rendering almost six times faster.
- Scott Jehl (2019). The Simplest Way to Load CSS Asynchronously.https://www.filamentgroup.com/lab/load-css-simpler/
- DoubleClick by Google (2016). The need for mobile speed: How mobile latency impacts publisher revenue.https://web.archive.org/web/20161007165422/https://www.doubleclickbygoogle.com/articles/mobile-speed-matters/
- Web Hypertext Application Technology Working Group (2020). HTML Living Standard. https://html.spec.whatwg.org/