Recently I had a chance to present a talk at NDC Sydney about web performance and it received a great feedback. That inspired me to write up a series of posts on each topic I covered in that talk, and who knows, maybe each of these posts would be a talk some day by their own 😃.
Link to all other parts:
OK, just to recap, here are the rules from part 1:
- Stream HTML to client
- Send minimal CSS and send it fast
In this part, we’re going to see how we can request our resources before we need them. You might be wondering why we want to do so, and the answer is, if you want to send minimal CSS to client, or any other resource for that matter, you need to break them into smaller pieces and load them separately.
There are some techniques which allow you to do it like lazy loading, but with lazy loading, user has to wait (most probably watching a spinner 😏) until the resource is loaded.
But, we can do better. One of the letters from PRPL pattern stands for
pre-cache. An effective way to load your resources before they are required, cache them and then use them when they are needed. We can achieve this using
prefetch features of browsers.
Before we go further into how, let me explain their difference:
<link rel="preload" as="script" href="super-important.js"> <link rel="preload" as="style" href="critical.css">
So by now you should have guessed that
preload is used in the current route and resources fetched via this technique are very important. The difference between using
rel=stylesheet is that browser will know about that resource way ahead of time allowing the download to start sooner.
If you are trying this for your stylesheet and don’t see your styles get applied, it is because there is a catch when using
<link rel="preload" as="style" href="critical.css" onload="this.rel='stylesheet'">
What happens now is that the styles get applied as soon as the file is loaded.
<link rel="prefetch"> is different from
<link rel="preload"> in that it is not trying to load a critical resource faster, it is trying to load a non-critical resource sooner.
Resources loaded by this technique are loaded after current page is loaded, page load event is finished and bandwidth is available. This means it is ideal for lazy loading future routes’ resources or resources that user might need later. Some use cases are fetching a next page if pagination is used:
<link rel="prefetch" href="page-2.html">
By the time user clicks on next page button, the page is already loaded and the app feels real fast.
To read more about the usage of these features and also know about other useful features, have a look at Google developer’s resource prioritisation page.
Same catch applied for
prefetch as well. But since we are loading a resource which is required potentially for a different route, you might have a separate
rel=stylesheet on that page which uses this in memory file or in case of a SPA just set the
stylesheet when the route is loaded.
When to use these
So to emphasise why we need to know about these techniques, let me take you back to part one. CSS is a render blocking element, so we need to break it down to the smallest possible chunk which is required to render our main route. Then we can use the above techniques to either load the resource later in the same page without blocking the rendering or to load the resource which is required for our possible next route beforehand and use it when needed.
Hope this has helped you to get started with optimising your HTML and CSS loading so far.
Next post will be on
Alla prossima 😎.