Preloading with care

Preloading with care

Resource hints or preloading is hot, I see it more and more in an attempt to (allegedly) improve website/shop performance, by preloading some assets.

About resource hints

Resource hints can be used to hint the browser about important resources, needed in the current or subsequent navigation. You can preload assest or perform DNS lookups ahead of time. For example:

  • when referencing to font-files hosted on other domains, preloading could be used;
  • resources needed for later navigation, could be prefetched;
  • when pulling in Google Analytics using Google Tag Manager, use preconnect or dns-prefetch.

Read more about resource hints on w3.org.

Preloading is relatively new, Chrome being the first browser to support preloading in version 50, as of April 2016. And it's purpose speaks for itself. But what happened is that we, developers, started to preload literally every asset. Some frameworks or build-tools will sometimes preload anything, even a stylesheet which is From performance perspective, this could become counterproductive.

Preloading stylesheets

One use case of preloading assets, is when you are lazyloading your stylesheet. Obviously, you only want to lazyload your stylesheet in combination with applying critical CSS, otherwise, the visitor would see an unstyled page for a while. In this use-case, the Critical CSS portion contains styling for main element above the fold.

Within the LightBolt CMS, we liked such an approach, to enable the browser to start rendering a styled page, without any render blocking resources in it's way. Our solution looked like the loadCSS solution, as introduced by Filament Group. But since July 2019, they advice to use another lazyloading CSS approach, where no preloading is involved.

preload fetches files very early, at the highest priority, potentially deprioritizing other important downloads, and that may be higher priority than you actually need

filamentgroup.com

Two advantages I see:

  • except for the onload-attribute, no JavaScript nor polyfills are needed. This is very convenient when you're already working with performance budgets, such as JavaScript kilobytes;
  • You, as a developer, isn't getting in the way of what the browser thinks is important. They are cleaver enough, no need to get in it's way!

Browser are even smarter; meet its look-ahead pre-parser

So, browser are pretty smart themselves and are build to do work as optimal as possible (but only if you as a developer did a great job as well). Browsers are even equipped with a so-called look-ahead pre-parser as of 2008.

Internet Explorer, WebKit and Mozilla all implemented pre-loaders in 2008 as a way of overcoming the low network utilisation while waiting for scripts to download and execute.

a 2013 article describing the pre-loader at andydavies.me

The browser's preloader also goes by the following names:

  • look-ahead pre-parser;
  • look-ahead downloader;
  • speculative pre-parser;
  • preload scanner;
  • browser pre-loader.

The latter might be a bit confusing, as we talked about the preload resource hint before. But at the same time, that's exactly what it does as well. We don't and even shouldn't preload everything we as developers consider important. Let browsers decide for themselves, instead of getting in the way of what we think is important.

No need to preload resources

With this knowledge, we now know we don't always have to preload our assets. When you are having references to external script files, but maybe placed them at the bottom of your HTML, you don't have to preload them.

Or, when building Client Side Rendered solutions, your HTML is very minimal, mainly referencing to JavaScript files. No need to preload them as well. You are better of preloading fonts at that stage, or other assets going to pulled in by other scripts.

Another example of an anti-pattern can be seen within Next.js. Not only script files at the bottom of an empty app shall, but also a render blocking stylesheet already being high up in the source is being preloaded with a seperate link-element. However, stylesheets are already given the highest priority by browsers. Another indicator or hint to give them priority using a resource hint just one line earlier, is redundant.

This [...] is trivial, as the browser probably discovers the <link rel=stylesheet> and <script> elements in the same chunk of HTML as the preloads

developer.mozilla.org

And as always, to answer the question if preload will or will not improve performance: it depends! Always keep testing, combine the use of Lighthouse with WebPageTest.org.

Preload analogy

I ran into this preload analogy later, and it actually illustrates very good what the result could be when using preload as you might interfere with default priority of resources. See preload as a queue-jump:

If you [...] get queue jumped into a club, it doesn’t only get you in quicker, it makes everyone behind you get in a little slower

Harry Roberts on Twitter

This can also be seen in this diagram. While you expect the preloaded file to be downloaded sooner (in this case, the image), it could come with a tradeoff where it fights over bandwith and priority, impacting the download of other resources.

Image via Robin Marx.

DNS prefech and preconnect

Wondering how this relates to using dns-prefetch and preconnect? Basically the same; often there is no need to do dns-prefecting or preconnecting for origins already present in the initially received HTML document.