Tutorial

How To Use Preload and Prefetch in HTML to Load Assets

HTML

Introduction

Loading assets on a page is an important part of achieving optimal web performance and a seamless user experience. Usually, real world apps load multiple CSS, font, JavaScript, and image files. These assets are render-blocking by default, which impairs loading performance.

In this tutorial, you will explore a new feature called resource hints, like preload and prefetch. These resource hints will allow you to overcome render-blocking.

Prerequisites

To complete this tutorial you will need the following:

  • Google Chrome downloaded and installed. This tutorial is built on version 86.0.4240.80 of Google Chrome.
  • An understanding of HTML, which you can find in the How To Build a Website with HTML series.
  • A basic understanding of JavaScript. This How to Code in JavaScript series help you achieve this.

Step 1 — Understanding Render-Blocking

When a request to a resource is render-blocking, it means that the window.onload event will not be triggered until that request finishes. In modern single page apps, most of the assets, like CSS and JavaScript files along with images, rely on this event in order to start operating. That means that parts of the UI will not start rendering or displaying on-screen until the render-blocking requests have finished loading.

To see this in action, create an HTML file with the standard boilerplate HTML in place. This can be done in your code editor of choice:

index.html
<!DOCTYPE html>
<html>
  <head>

  </head>
  <body>

  </body>
</html>

In the head, use the <link> tag to access your Google Font of choice. This code snippet will use Roboto:

index.html
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href='https://fonts.googleapis.com/css?family=Roboto:400,600|Material+Icons'>
  </head>
  <body>

  </body>
</html>

Add <style> tags. Using CSS, set the font-family for all p tags to Roboto:

index.html
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href='https://fonts.googleapis.com/css?family=Roboto:400,600|Material+Icons'>
      <style>
      p {
        font-family: Roboto;
      }
    </style>
  </head>
  <body>

  </body>
</html>

With your metadata and CSS in place, you can create a <p> within the <body> that says Hello:

index.html
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href='https://fonts.googleapis.com/css?family=Roboto:400,600|Material+Icons'>
    <style>
      html {
        font-family: Roboto;
      }
    </style>
  </head>
  <body>
    <p> Hello </p>
  </body>
</html>

To see the render blocking in action, add <script> tags within the <body>. Create a JavaScript function using window.onload that will console.log the message 'Loaded':

index.html
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href='https://fonts.googleapis.com/css?family=Roboto:400,600|Material+Icons'>
    <style>
      html {
        font-family: Roboto;
      }
    </style>
  </head>
  <body>
    <p> Hello </p>

    <script>
      window.onload = function () {
        console.log('Loaded');
      }
    </script>
  </body>
</html>

With your code in place, open your HTML file in Chrome. Next, open Developer Tools and navigate to the Network tab. Lower the connection to Slow 3G and then reload the page.

The Loaded message is logged in the console right after the CSS file is loaded, as the next image shows:

Load without preload

This effect becomes more problematic when building and loading larger websites. Your CSS and JavaScript assets, along with many others, may take a long time to load. Therefore, your CSS styles may not display immediately. Preloading resources can eliminate this effect and prevent delayed loading.

Step 2 — Preloading Resources

To prevent the default render-blocking and to make sure that page resources like fonts and CSS start loading early in the page life cycle, you will need to implement preloading. The rel="preload" attribute value is used to preload assets. It can be applied to several file formats, including CSS, JS, fonts, images, and more. Depending on the type of file you would like to preload, the corresponding as attribute may also need to be included along with rel="preload". For CSS, as= will need to be set equal to "style". For JavaScript, as= will need to be set equal to "script".

Return to the HTML file and change the previous <link>. Set rel equal to "preload". Add the as attribute set equal to "style":

index.html
<head>
    <link
      rel="preload"
      as="style"
      href='https://fonts.googleapis.com/css?family=Roboto:400,600|Material+Icons'>
    <style>
      html {
        font-family: Roboto;
      }
    </style>
  </head>

With your HTML file opened in Google Chrome, return to Developer Tools and load the page with Network still set to Slow 3G. You’ll see that the Loaded log shows up right before the CSS request starts, as the following image shows:

Load using preload

However, you may have noticed that the CSS style hasn’t been applied to the text. That’s because using preload or prefetch only fetches the resource, but it doesn’t apply it. Instead, preload and prefetch will keep the resource in memory. You have to define when the resource will be loaded.

The font needs to be applied as soon as it loads. To make this happen, add the onload attribute to the <link> tag. Set onload equal to "this.rel = 'stylesheet'":

index.html
<link
  rel="preload"
  as="style"
  onload="this.rel = 'stylesheet'"
  href='https://fonts.googleapis.com/css?family=Roboto:400,600|Material+Icons'>

By setting the rel attribute to stylesheet in onload, the browser is told to use the resource. Since it’s been already downloaded in memory, it doesn’t download it again.

Since the onload solution relies on JavaScript, add <noscript> tags which contain the original <link> tags with rel set to "stylesheet":

index.html
<link
  rel="preload"
  as="style"
  onload="this.rel = 'stylesheet'"
  href='https://fonts.googleapis.com/css?family=Roboto:100,900|Material+Icons'>
<noscript>
  <link
    rel="stylesheet"
    href='https://fonts.googleapis.com/css?family=Roboto:400,600|Material+Icons'>
</noscript>

This will ensure that the font displays if JavaScript is disabled or fails to load.

You now know how to preload your web page assets. There are times when you may want to prefetch your resources instead.

Step 3 — Prefetching Resources

Prefetching works similarly to preloading. The difference is that, when prefetching a resource, the browser considers the resource to be low priority. This means that the resource or asset will load a bit later. Because of this, prefetching is usually implemented with resources that are not required initially, but are used at a later point.

To implement prefectching in your HTML page, change the value of rel to "prefetching":

index.html
<link
  rel="prefetch"
  as="style"
  onload="this.rel = 'stylesheet'"
  href='https://fonts.googleapis.com/css?family=Roboto:100,900|Material+Icons'>

Prefetching and preloading CSS can help improve web performance. You may want to apply preloading to your JavaScript as well. Preloading JavaScript is different from preloading CSS resources.

Step 4 — Preloading JavaScript

Preloading JavaScript resources is done differently. This example, taken from this Google Developers article on preloading, shows this:

index.html
<link rel="preload" href="used-later.js" as="script">
<!-- ... -->
<script>
  var usedLaterScript = document.createElement('script');
  usedLaterScript.src = 'used-later.js';
  document.body.appendChild(usedLaterScript);
</script>

Note: Code snippet reproduced from work created and shared by Google and licensed under the Apache 2.0 License.

The important step here is setting the src attribute of the file and inserting it into the DOM.

Conclusion

Preloading and prefetching allows you to control how resources are loaded and helps boost web performance. With this tutorial, you implemented resource hints to preload and prefetch resources like CSS, fonts, and JavaScript. This will help you to create faster progressive web apps.

To create progressive web apps with Angular, this How To Build Progressive Web Apps with Angular tutorial can accomplish that. If you prefer Vanilla JavaScript, this How to Build a PWA in Vanilla JavaScript tutorial can help you.

Creative Commons License