The Critical Request: How to Prioritise Requests to Improve Speed

Ben Schwarz

Ben Schwarz

April 26, 2021

Illustrated by

 Jeffrey Phillips

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.

What is asset prioritisation?

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:

Visualisation of how a site is analysed and its resources prioritised.
Visualisation of how a site is analysed and its resources prioritised.

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.

This article features Chrome, but other browsers prioritise requests similarly. You can view request priority in Chrome, Safari, Firefox or Edge developer tools by right-clicking on any table title and choosing “Priority”.
How to enable the “Priority” column to inspect request priority in Chrome Developer Tools
How to enable the “Priority” column to inspect request priority in Chrome Developer Tools.

Request priority can also be seen in Chrome’s Performance tab:

How to investigate resource timings and priorities in the Chrome Developer tools Performance Panel.
How to investigate resource timings and priorities in the Chrome Developer tools Performance Panel.

How does Chrome prioritise resources?

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 TypePriority
Stylesheets loaded with @importHighest, will be queued after blocking scripts.
ImagesDefault priority Low, upgraded to Medium when rendered in the initial viewport.
JavaScriptsLow, Medium or High. See Addy Osmani’s JavaScript Loading Priorities in Chrome for more details.
Ajax, XHR, or fetch() APIHigh

What makes a request critical?

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:

The content critical to the viewer is the masthead and the leading article.
The content critical to the viewer is the masthead and the leading article.

For this page, the critical requests are:

  1. HTML
  2. CSS
  3. Logo
  4. Three webfont weights
  5. Leading article image (Largest Contentful Paint element)

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:

  • Perform a visual audit of the page, note above-the-fold critical elements.
  • The first 5 HTTP requests should be: HTML + 4 Critical requests.
  • Make sure no critical requests are redirected.
  • Update your site to ensure critical resources are optimised, compressed, served with caching & correct HTTP headers.

Lighthouse Audit: Avoid chaining critical requests

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.

Example of Avoid Critical Requests Chain Lighthouse Audit
Example of Avoid Critical Requests Chain Lighthouse Audit

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');
9.carousel-bg {
10 background-image: url('/images/main-masthead-bg.png');

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:

  • Reduce the number of requests
  • Reduce the size of resources using compression and minification
  • Mark non-critical scripts as async
  • Consider inlining @font-face declarations directly into HTML
  • Avoid using CSS background images or @import
  • Use preload to retreive critical resources earlier
  • Look for smaller library alternatives using bundlephobia

Technique: Control request priority

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 />
Before and after prioritising webfont assets. After, the fonts are fetched with high priority.
Before and after prioritising webfont assets. After, the fonts are fetched with high priority.

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.

Technique: Lazy loading images

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:

  • loading=” lazy” attributes are added to <img /> elements that are known to appear below-the-fold.
  • As the page is scrolled, deferred lazy images are loaded, ready to be displayed.
Cumulative Layout Shift (CLS) identifies page layout shifts during user interactions. Be sure to set width and height attributes on images to avoid the page re-calculating layout when a lazily loaded image loads.

That’s it! Lazy loading is uncomplicated to implement and effective in speeding up rendering. Use it wherever you can.

Technique: font-display

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.

You can use font-display to improve Largest Contentful Paint and Cumulative Layout Shift (two out of three Core Web Vitals metrics).

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;

The browser will display Helvetica (or Arial, if your system doesn’t have Helvetica installed) until the Calibre font has loaded.

Without font-display

Text appears after the HTML, CSS, and webfonts are loaded:

Without font-display, text is shown at 2.44 seconds.
Without font-display, text is shown at 2.44 seconds.

With font-display: swap

Text appears as soon as the HTML is downloaded and evaluated, yielding a 1.6 second improvement:

With font-display: swap, text is shown at 835 milliseconds.
With font-display, text is shown at 835 milliseconds.

font-display is well supported in the majority of modern browsers, so you can start using it today.

Critical Request checklist

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:

  • Enable the Priority column in Chrome Developer Tools.
  • Reduce the number of required critical requests where possible.
  • Audit which requests must be made before users can see a fully rendered page. Prioritise these critical requests with <link rel="preload" />.
  • Use link prefetching for assets that are likely to be used on the next navigation.
  • Use Link Preload HTTP headers to declare resources to be preloaded before the HTML is fully delivered.
  • Ensure image dimensions are correctly sized.
  • Use Inline SVGs for Logotypes and Icons.
  • Use better image formats like AVIF or WEBP.
  • Use font-display: swap to display text on the initial render.
  • Use compressed font formats like WOFF2 or variable fonts.
  • View Chrome’s network events at chrome://net-internals/#events.
  • Remember: the fastest requests are the ones you never make.

Happy optimising!

Ben Schwarz

Ben Schwarz

Ben is the Founder and CEO of Calibre. He uses his experience in far-reaching Open Source projects and web standards to build tools for a better, more accessible web. Find him on Mastodon or LinkedIn.

Become a site speed expert

Join thousands of subscribers keeping up-to-date with web performance news and advice.

The best performance newsletter I’ve come across. Highly recommended.

Addy Osmani

Addy Osmani

Engineering Manager at Google Chrome