Understanding CSS preload and other resource hints

Modern web browsers use various optimization techniques to render pages fast. These techniques depend on many factors — the type of device the user is using, the network connectivity, as well as available memory resources, to mention a few. The techniques work well but there is room for improvement.

As a developer, you need better insights into the critical resources needed for your page. Leaving the browser to make all the decisions can sometimes result in critical resources being deferred.

To solve this problem, browsers introduced resource hints: preload, prefetch, and preconnect. The resource hints allow you to provide instructions to the browser to properly prioritize the fetching of critical resources on your page.

In this tutorial, we will look at these browser resource hints: preload, prefetch, and preconnect. We will explore their benefits and best practices for using them.

Jump ahead:

What are CSS resource hints?

Resource hints are instructions and suggestions to the browser on how to handle specific resources on the page to optimize page performance.

With resource hints, you can do the following:

  • Provide mandatory instructions to the browser to fetch and cache a resource much sooner than it would have done otherwise
  • Tell the browser to perform a DNS lookup for referenced resources that reside on external domains
  • Make suggestions to the browser to fetch resources for the next page in advance

CSS preload

When the browser loads a webpage, it parses the document and issues requests for the resources referenced in the document. It makes its best judgment of which resources are critical and should be fetched first. Sometimes, the browser will overlook critical resources and defer them for later when they shouldn’t be deferred.
The rel="preload" resource hint allows you to force the browser to fetch a resource much sooner than it would have without preload. But the browser doesn’t execute the fetched resource; instead, it stores the resource in the cache. Then, when the browser reaches the part of the document that references the resource, it is retrieved from the cache and executed.

How to use CSS preload

If you deem a resource critical, you need to add rel="preload" to the link tag nested inside the head tag, as demonstrated below:

<head>
  <link rel="preload" as="script" href="https://blog.logrocket.com/understanding-css-preload-other-resource-hints/critical-script.min.js" />
</head>

The as attribute helps the browser anticipate the resource type, which is helpful for setting the correct headers and checking if a resource has been cached. It is a crucial part of preloading a resource, and should not be omitted.

The following are some of the more common values you can use for the as attribute:

  • style: CSS files
  • script: JavaScript files
  • font: Web fonts
  • image: Images
  • video: Web videos
  • audio: Music or audio files
  • worker: Web worker

For a comprehensive list, visit MDN.

Preloading fonts with CSS preload

When preloading fonts, you must also include a crossorigin attribute in addition to the as attribute:

<link rel="preload" href="https://blog.logrocket.com/understanding-css-preload-other-resource-hints/font-name.woff2" as="font" type="font/woff2" crossorigin>

Failure to include it may result in it the browser downloading the font twice. The crossorigin attribute is only needed for preloading fonts.

If you are generating link elements in JavaScript, you can preload them as follows:

<script>
    const link = document.createElement("link");
    link.rel = "preload";
    link.as = "script";
    link.src = "https://blog.logrocket.com/understanding-css-preload-other-resource-hints/js/main.js";
    document.head.appendChild(link);
</script

The above code describes how to preload a resource in the link tag, but is not the only option available. You can also use theLink HTTP header as follows:

Link: <critical.js>; rel="preload"; as="script"

The advantage of the HTTP header is that the browser doesn’t have to parse the document to know which resources it should preload.

To include multiple preloading hints with the Link HTTP header, you can separate them with commas:

Link: <critical.css>; rel="preload"; as="style", </script.js>; rel="preload"; as="script"

Best practices when using preload

Using rel="preload" can have a greater effect on improving page performance. It can sometimes be destructive, the following are some of the best practices to keep in mind:

  • Use rel="preload" sparingly and only for the resources that are critical to the page’s initial rendering.
  • Always use the as attribute when you preload a resource. Omitting it can result in the browser sometimes fetching the same resource twice.

Double-check that a preloaded resource is going to be used within 3 seconds or else Chrome will complain:

The resource was preloaded using link preload but not used within a few seconds from the window’s load event. Please make sure it has an appropriate as value and it is preloaded intentionally

The support for rel="preload" is good, and if the browser doesn’t support preloading, it will simply ignore the attribute:

Browser compatibility for preload. Source: CanIUse.com

That takes care of preloading. We will look at prefetching next.

How to use prefetch

Users like websites that load fast, and another way you can speed up the page load is to use rel="prefetch". For example, if you know — either through your website’s analytics or the presence of a specific workflow within your app — that users are more likely to start on a given page and move to a specific second one, you can use prefetching to load that second page in advance.

With prefetching, you can add rel="prefetch" on a link to a popular page so that the browser can download the resources for that page in advance during its idle time. When the user decides to move to the next page, that page will load faster because the resources have been cached.

This works well for resources such as CSS files or scripts that will be needed on the next page. As an example, Netflix was able to reduce their time-to-interactive metric for future navigations by 30 percent by prefetching React when users are logged out.

To use the prefetch resource hint, add it on a link tag inside the head element like so:

<head>
  ...
   <link rel="prefetch" href="https://blog.logrocket.com/products/" as="document">
  ...
</head>

In the preceding link tag, you prefetch the resources for a /products page. Similar to preloading, we also include the as attribute to help the browser set the correct headers.

You can prefetch any link of your choosing, just make sure that you are certain that users will navigate to it next.

You can also prefetch a resource using the Link HTTP header:

Link: </css/style.css>; rel=prefetch

The following is the browser compatibility table for rel="prefetch":

Browser compatibility for rel="prefetch"
Browser compatibility for rel="prefetch". Source: CanIUse.com

DNS prefetch using rel="dns-prefetch"

When the browser wants to fetch a resource from an external domain, it uses DNS to translate the domain name to an IP address. This process can take a couple of milliseconds. If you have links to resources on another domain or a CDN, you can use rel="dns-prefetch" to tell the browser to do a DNS lookup in advance.

To use it, we can do it as follows:

<link rel="dns-prefetch" href="http://example.com">

The browser will do a DNS lookup for that preceding link in advance, and during parsing, it will just request a resource from the server.

The following is the browser compatibility for prefetch:

Browser compatibility for prefetch
Browser compatibility for prefetch. Source: CanIUse.com

Best practices when using prefetch

To use rel="prefetch" properly, keep the following in mind:

  • Use it only for resources that you know the user will visit next. For a hint, look at popular pages in your analytics
  • Avoid using it on slower connections because it can use a lot of bandwidth

prefetch vs. preload

In this section, we will look at the difference between preload and prefetch to avoid confusing the two.

rel="preload" is a fetch directive that forces the browser to download a resource, such as a CSS or JavaScript file, sooner because we, as developers, know that the resource will be needed much sooner. The browser does not execute the file; instead, it caches the file in the disk and executes it only when it parses part of the document that references the file.

rel="prefetch" is a resource hint that tells the browser to download a resource during its idle time without interfering with the fetching of important files on a page. This is a low-priority download, and the browser can choose to ignore it. Once the file is downloaded, it is stored in the cache and the browser won’t immediately execute it. The file is retrieved from the cache when the user visits another page, which makes the page load faster. This is because retrieving the file from the cache is faster than making a network request.


More great articles from LogRocket:


What is preconnect?

Another helpful resource hint is rel="preconnect", which tells the browser that your page contains external domain references, and you want the browser to establish the connection to the external domain servers as soon as possible because they are important to your page.

For example:

<link href="https://example.com/main.css">

Here, we request a main.css file from the example.com server. The browser does the following to fetch the resource:

  • DNS lookup: The browser performs a DNS lookup to translate example.com to an IP address. This process can take a couple of milliseconds, as multiple requests are sent to the DNS servers that return the IP address to the browser
  • Establishing connection: Once the browser has the IP address, it will establish a connection to the server through a process known as a three-way handshake
  • Fetch the object: With the connection established, the first server will send the object to the second server

If you have multiple references to other domains from the page, the browser will have to perform the DNS lookup and establish the connection for each external link.

With rel="preconnect", you can tell the browser to do the DNS lookup and establish the connection ahead of time, while the browser is rendering the page contents. These will help the page to load more quickly.

How to use preconnect

To preconnect a resource, we need to add rel="preconnect" to a link that references an external domain like so:

<link rel="preconnect" href="https://example.com/main.css">

This tells the browser to establish a connection to the example.com server before it executes this line.

We can also use the Link HTTP header:

Link: <https://example.com/>; rel=preconnect

Best practices for using preconnect

The following are some of the recommended practices you should follow to make the best out of it:

  • Use rel="preconnect" for external domain references and avoid using it on links referencing your site resources
  • Use preconnect on critical domains that you know the browser will use soon; otherwise, the browser will close the connection if it has not been used for more than 10 seconds. This wastes CPU time

The following is the browser compatibility table:

Browser compatibility for preconnect
Browser compatibility for preconnect. Source: CanIUse.com

Remember that if a browser doesn’t support the option, it will simply ignore it. So feel free to use preconnect when you see fit.

Conclusion

In this tutorial, we learned how to use resource hints: preload, prefetch, and preconnect. We looked at the benefits and best practices of using each resource hint to speed up the page. You are now equipped with the knowledge to speed up the pages of your application

Is your frontend hogging your users’ CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.https://logrocket.com/signup/

LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web and mobile apps — .


Source link