Ben Schwarz
April 26, 2021
Illustrated by
Serving a website seems pretty straightforward: send down some HTML, the browser figures out what resources to load next. Then, we wait patiently for the page to be ready.
Little did you know, a lot is going on under the hood. Have you ever wondered how the browser figures out which assets should be requested and in what order?
Today, we’re going to explore how browsers evaluate request priority and how to alter it to improve page render speed.
Modern browsers parse HTML using a streaming parser—assets are found within the markup before it has been fully downloaded. As the browser discovers assets, it adds them to a network queue with a predetermined priority:
The predetermined priority could be one of: Lowest, Low, Medium, High and Highest. By assigning priority, the browser can then understand which requests are the most crucial for the page to be loaded quickly.
Request priority can also be seen in Chrome’s Performance tab:
Resources are added to the network queue in order of appearance or discovery. The browser then dedicates network activity to fetching the Highest priority resources as quickly as possible.
Each resource type has its own set of rules that dictate the priority assigned to it:
Resource Type | Priority |
---|---|
HTML | Highest |
Fonts | High |
Stylesheets | Highest |
Stylesheets loaded with @import | Highest, will be queued after blocking scripts. |
Images | Default priority Low, upgraded to Medium when rendered in the initial viewport. |
JavaScripts | Low, Medium or High. See Addy Osmani’s JavaScript Loading Priorities in Chrome for more details. |
Ajax, XHR, or fetch() API | High |
Critical Request is a resource that is displayed in the initial viewport of a page.
These resources have a direct impact on Core Web Vitals metrics like Largest Contentful Paint and First Contentful Paint. Using this article as an example, we can visually identify assets that are required for the viewport to be fully rendered:
For this page, the critical requests are:
These assets (note the lack of JavaScript) are essential to the initial viewport’s visuals. They should be loaded first.
When auditing your pages, we recommend:
Google’s Lighthouse suite comes with an audit titled “Avoid chaining critical requests” that highlights requests chained together. When a browser makes a request after another request references it (also known as a dependency), we call it a request chain.
One of the most common examples of a critical request chain is a stylesheet that loads a font or background image that is displayed within the initial page viewport:
1@font-face {2 font-family: 'Calibre';3 font-weight: 400;4 font-display: swap;5 src: url('/Calibre-Regular.woff2') format('woff2'), url('/Calibre-Regular.woff')6 format('woff');7}89.carousel-bg {10 background-image: url('/images/main-masthead-bg.png');11}
You can use Lighthouse’s Avoid Critical Request Chain audit to help diagnose and identify resource dependencies on your page.
Reducing the overall number of critical request chains will result in faster Largest Contentful Paint and a more instant user experience.
To reduce the impact of critical request chains, use these web performance strategies:
Request priority can be influenced using preload. Preloaded resources are assigned as High priority and are fetched earlier during the page’s initial load.
1<link rel="preload" href="Calibre-Regular.woff2" as="font" crossorigin />
With preload, you’re telling the browser: “You might not know it yet, but we’re going to need this.”
Preload helps optimise critical requests, but don’t go overboard! If too many resources are preloaded, page performance can deteriorate.
Preloading can impact Largest Contentful Paint and Cumulative Layout Shift. In some cases, that impact can be negative. We recommend experimenting with preloading requests, but be sure to test before and after.
By default, browsers load all images specified in HTML, even if users never actually view them. Lazy loading allows you to specify images that should only be fetched when a user scrolls near them. If the user never scrolls, the browser won’t load those images.
With this approach, you can improve overall rendering speed and save needless data transfer. Lazy loading is effective in improving Largest Contentful Paint (LCP).
Historically, we implemented lazy load using third-party libraries or hand-crafted scripts. Today, it’s built into browsers.
Here’s how it works:
That’s it! Lazy loading is uncomplicated to implement and effective in speeding up rendering. Use it wherever you can.
According to HTTP Archive, 69% of sites use web fonts, and unfortunately, they’re providing a sub-par experience in most cases.
Everyone has witnessed fonts that appear, then disappear, change weights and jolt the page. Those shifts are now measured by Cumulative Layout Shift metric.
As we have already demonstrated with <link rel= “preload”/>, controlling the request priority of fonts has a staggering effect on render speed. It’s clear that we should be looking to prioritise web font requests in most cases.
We can make further render speed improvements using CSS font-display. This CSS property allows you to control how fonts display during web fonts being requested and loaded.
There are five font-display options at your disposal. We recommend the swap option, which immediately renders text, then replaces the webfont as soon as it has loaded.
Given this font stack:
1body {2 font-family: Calibre, Helvetica, Arial;3}
The browser will display Helvetica (or Arial, if your system doesn’t have Helvetica installed) until the Calibre font has loaded.
Text appears after the HTML, CSS, and webfonts are loaded:
Text appears as soon as the HTML is downloaded and evaluated, yielding a 1.6 second improvement:
font-display is well supported in the majority of modern browsers, so you can start using it today.
With this knowledge, you should now be able to select the most critical assets for your site and prioritise them accordingly. If you’d like to push prioritisation and speed even further, follow the checklist below:
Happy optimising!
Join thousands of subscribers keeping up-to-date with web performance news and advice.
Addy Osmani
Engineering Manager at Google Chrome