How to control the priority of Web resource loading?

Hello, I'm Conard Li. Today, let's take a look at the priority of Web resource loading.

The browser resolves the priority of the resource

When the browser starts parsing web pages and downloading resources such as pictures, scripts and CSS, the browser will assign a fetch priority flag representing the download priority of resources to each resource.

The order of resource downloading depends on this priority flag, and the calculation logic of this priority flag will be affected by many factors:

  • Different resource types such as Script, CSS, Font and Image have different priorities.
  • The location or order in which resources are referenced in HTML documents will also affect the priority of resources (for example, image resources in the viewport may have a high priority, while CSS loaded in the < link > tag that blocks rendering has a higher priority).
  • Resources with the preload attribute can help the browser discover resources faster. In fact, it also affects the priority of resource loading.
  • The async or defer attribute of a Script affects its priority.

Considering these factors, the following is the priority and ranking of most resources in Chrome:

The browser downloads resources with the same calculation priority in the order in which the resources are found. You can see the priorities assigned to different resources under DevTools Network:

Although browsers are good at this, the default download priority is not the best in all cases.

Why do you need Priority Hints?

Knowing how the browser assigns download priority to resources, we can make some adjustments according to the actual business scenario:

  • Resource tags are placed according to the desired download order of resources, such as < script > and < link >, and resources with the same priority are usually loaded in the order in which they are placed.
  • Use the preload attribute to download necessary resources in advance, especially those that are not easy to find in the early stage of the browser.
  • Use async or defer to download non first screen resources that do not need to be blocked.
  • Delay loading some first screen content so that the browser can use the available network bandwidth for more important first screen resources.

These technologies can let us better control the priority calculation of the browser, so as to improve the Core Web Vitals performance index of the web page. For example, we can improve the maximum content rendering index (LCP) by preloading the key background images of web pages.

However, the above technologies are not enough for us to control the priority in all scenarios, such as the following scenarios:

  • The website now has multiple first screen images, but they do not have the same priority. For example, in the rotation map, only the first image needs higher priority.
  • Declaring < script > as async or defer tells the browser to load them asynchronously. However, according to our analysis above, these < script > are also assigned "low" priority. But you may want to make sure that browsers download them asynchronously while raising their priority, especially some scripts that are critical to the user experience.
  • The browser assigns high priority to the JavaScript fetch API to asynchronously obtain resources or data, but in some scenarios, you may not want to request all resources with high priority.
  • The browser assigns the same high priority to CSS and Font, but not all CSS and Font resources are equally important. You may need to specify their priority more specifically.

Therefore, the browser provides us with a function that can better control the priority loading of resources: Priority Hints.

importance property

You can use an importance attribute to more carefully control the priority of resource loading, including link, img, script and iframe tags.

The importance property can specify three values:

  • High: you think this resource has high priority and want the browser to prioritize it.
  • low: you think this resource has a lower priority and want the browser to lower its priority.
  • auto: uses the browser's default priority.
<!-- We don't want a high priority for this above-the-fold image -->
<img src="/images/in_viewport_but_not_important.svg" importance="low" alt="I'm an unimportant image!">

<!-- We want to initiate an early fetch for a resource, but also deprioritize it -->
<link rel="preload" href="/js/script.js" as="script" importance="low">

<script>
  fetch('https://example.com/', {importance: 'low'}).then(data => {
    // Trigger a low priority fetch
  });
</script>

<!-- The third-party contents of this iframe can load with a low priority -->
<iframe src="https://example.com" width="600" height="400" importance="low"></iframe>

practical application

Raise the priority of LCP images

Now that you have more flexible priority configuration, you can use it to improve the Core Web Vitals of your web pages.

For example, in Google Flights, the main reason affecting its LCP index is its background image. Now we use the importance attribute to improve its loading priority:

<img src="lcp-image.jpg" importance="high">

It can be found that the LCP of the web page has increased from 2.6s to 1.9s:

Reduce the priority of the first screen picture

Use the importance attribute to lower the priority of the first screen picture that may not be important, such as the following picture in the rotation picture:

<ul class="carousel">
  <img src="img/carousel-1.jpg" importance="high">
  <img src="img/carousel-2.jpg" importance="low">
  <img src="img/carousel-3.jpg" importance="low">
  <img src="img/carousel-4.jpg" importance="low">
</ul>

Reduce the priority of preloaded resources

To prevent competition between preloaded resources and other critical resources, you can lower their priority:

<!-- Lower priority only for non-critical preloaded scripts -->
<link rel="preload" as="script" href="critical-script.js">
<link rel="preload" href="/js/script.js" as="script" importance="low">

<!-- Preload CSS and hero images without blocking other resources -->
<link rel="preload" as="style" href="theme.css" importance="low" onload="this.rel=stylesheet">

Priority of script

If there are some necessary interactive scripts on the page, but there is no need to block other resources, you can mark them as having high priority and load them asynchronously:

<script src="async_but_important.js" async importance="high"></script>

If scripts depend on specific DOM nodes, they cannot be marked as loaded asynchronously. However, if they are not necessary for first screen rendering, you can lower their priority:

<script src="blocking_but_unimportant.js" importance="low"></script>

fetch

The browser will execute fetch requests with high priority by default. You can lower the priority of less critical data requests:

// Important validation data (high by default)
let authenticate = await fetch('/user');

// Less important content data (suggested low)
let suggestedContent = await fetch('/content/suggested', {importance: 'low'});

Start trial

You can try this feature by opening Experimental Web Platform Features in Chrome settings.

reference resources

https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/1.5/Changing_the_priority_of_HTTP_requests

https://developer.chrome.com/blog/new-in-chrome-96/#pri-hints

https://web.dev/priority-hints/

Posted by Hard Styler on Wed, 01 Dec 2021 20:15:42 -0800