Translate: calibreapp.com/blog/critic… Ben Schwarz, with permission from the author. This article was originally published on the ByteDance Web Infra account.

preface

The ByteDance Web Infra team focuses on front-end performance in two areas, focusing on performance optimization from code and monitoring, respectively.

There are many aspects to performance optimization, one of which is prioritizing key requests to achieve performance optimization. This paper discusses the method in a relatively systematic way. We also welcome interested readers to pay attention to us and communicate with us.

Building a web service is deceptively simple: send the HTML, and the browser recognizes what resources need to be loaded next. Then, we wait patiently for the page to be ready.

What you don’t know is, there’s a lot going on behind the scenes. Have you ever wondered how the browser determines which assets need to be requested in what order?

Content Overview:

  1. What is asset priority?
  2. How does Chrome prioritize resources?
  3. What kind of request is critical?
  4. Lighthouse Auditing: Avoid chains of dependencies for critical requests.
  5. Technology: Control request priority.
  6. Technology: lazy loading of images.
  7. Technology: the font display
  8. Critical request checklist.

What is asset priority?

Modern browsers use streaming parsers to parse HTML – assets can be found in HTML tags before they are fully downloaded. When the browser finds assets, it adds them to the network queue at a predetermined priority.

Visually analyze a site and its resource priorities.

The pre-determined priorities may be: Lowest, Low, Medium, High, and Highest. By prioritizing, the browser knows which requests are most critical for fast page loading.

This article focuses on Chrome, but other browsers prioritize requests similarly. You can view request priority in Chrome, Safari, Firefox, or Edge developer tools by right-clicking on any table title and selecting priority.

The request priority can also be seen in Chrome’s Performance panel:

How does Chrome prioritize resources?

Resources are added to the network queue in the order they appear. The browser then devotes network activity to getting the highest priority resources as quickly as possible.

Each resource type has its own set of rules to determine the priority assigned to it:

The resource type priority
HTML Highest
Fonts High
Stylesheets Highest
Stylesheets loaded with @import Highest will be placed after the blocking script.
Images The default is Low and is upgraded to Medium for initial viewport rendering.
JavaScripts Low, Medium or High. Check out Addy Osmani’sJavaScript Loading Priorities in ChromeFor more details.
Ajax, XHR, or fetch() API High

What kind of request is critical?

Key requests are resources that are displayed in the initial viewport of the page.

These resources have a direct impact on metrics such as Largest Contentful Paint and First Contentful Paint in Core Web Vitals. Using this article as an example, we can intuitively identify the assets that viewports need in order to render fully.

The key request for this page is:

  1. HTML
  2. CSS
  3. LOGO
  4. Three word weights
  5. Largest Contentful Paint

These resources (note, no JavaScript) are essential for the initial visual presentation of the viewport. They should be loaded first.

When auditing your pages, we recommend:

  • Perform a visual audit of the page, focusing on key elements in the viewport.
  • The first five HTTP requests should be: HTML + 4 key requests.
  • Ensure that critical requests are not redirected.
  • Update your site to ensure that key resources are optimized, compressed, cacheable, and have the correct HTTP headers.

Lighthouse Auditing: Avoid chains of dependencies for critical requests

Google’s Lighthouse suite comes with an audit called “Avoid Chains of Dependencies for Critical Requests,” which highlights requests that are linked together. When the browser makes a request because another request refers to it (also called a dependency), we call it a request chain.

One of the most common examples of critical request chains is when some stylesheets load fonts or background images internally that are displayed in the initial page viewport.

@font-face {
  font-family: 'Calibre';
  font-weight: 400;
  font-display: swap;
  src: url('/Calibre-Regular.woff2') format('woff2'), url('/Calibre-Regular.woff') format('woff');
}

.carousel-bg {
  background-image: url('/images/main-masthead-bg.png');
}
Copy the code

You can use Lighthouse’s avoiding Dependency Chains of Critical Requests audit to diagnose and identify resource dependencies in your pages.

Reducing the overall number of key request chains makes for faster Largest Contentful Paint and instant user experience.

To reduce the impact of critical request chains, use the following Web performance policies:

  • Reduce the number of requests
  • Use compression and minimization to reduce the size of resources
  • Mark non-critical scripts as asynchronous
  • consider@font-faceDeclarations are directly inlined into HTML
  • Avoid using CSS background images or@import
  • Use preloading to get critical resources ahead of time
  • Use BundlePhobia to find smaller alternatives to the library

Technology: Control request priority

Request priority can be affected by the use of preload. Pre-loaded resources are assigned high priority and are requested first during the initial load of the page.

<link rel="preload" href="Calibre-Regular.woff2" as="font" crossorigin />
Copy the code

With Preload, you tell the browser, “You may not know what it is yet, but we need it.”

Preloading helps optimize critical requests, but don’t abuse it! If too many resources are preloaded, page performance degrades.

The Largest Contentful Paint and Cumulative Layout Shift are affected by preloading. In some cases, the impact can be negative. We recommend experimenting with preload requests, but be sure to test them carefully before and after.

Technology: lazy loading of images

By default, browsers load all images specified in HTML, even those the user will never actually see. Lazy loading allows you to specify that certain images are requested only when the user scrolls the page near them. If the user doesn’t scroll, the browser won’t load the images.

Using this approach, you can improve overall rendering speed and save on unnecessary data transfers. Lazy loading is an effective way to improve maximum Contentful Paint.

In the past, we used third-party libraries or hand-written scripts for lazy loading. It is now built into the browser.

The usage method is as follows:

  • It’s already known to be under the viewport<img />Plus theta to the elementloading="lazy"Properties.
  • When the page scrolls, the lazy images are loaded and ready for display.

Cumulative layout offset (CLS) identifies page layout offset during user interaction. Be sure to set the width and height attributes of the image to avoid lazy loading of images during rendering and the page being rearranged.

That’s it! Lazy loading is not complicated to implement, but it is very helpful for speeding up rendering. Make sure you use as much as possible.

Technology: the font display

According to statistics from HTTP Archive, 69% of sites use Web fonts. Unfortunately, unfortunately, in most cases, they provide sub-par experiences.

Everyone has seen fonts appear and then disappear, changing their thickness and shaking the page. These shifts are now measured by the cumulative layout shift (CLS) indicator.

We have demonstrated that controlling the priority of font requests with has a surprising effect on rendering speed. So obviously, we should increase the priority of font requests in most cases.

We can use CSS font-display to further improve rendering speed. This CSS property allows you to control how fonts are presented when requested and loaded.

You can use font-display to optimize the Cumulative Layout Shift and Largest Contentful Paint.

There are five font-display options to choose from. We recommend using the swap option, which renders text immediately and then replaces web fonts immediately after loading.

Given a font stack like this:

body {
  font-family: Calibre, Helvetica, Arial;
}
Copy the code

Browsers will display the font in Helvetica (or Arial, if you don’t have Helvetica installed on your system) until Calibre is loaded.

Without the font display

Text is displayed after HTML, CSS, and web fonts are loaded:

No font-display, text is displayed in 2.44 seconds.

Along with the font – display: swap

Text is displayed as soon as the HTML is downloaded and processed, a 1.6 second improvement:

Using font-display, the text is displayed in 835 milliseconds.

Font display works well in major modern browsers, and you can start using it today.

Critical request checklist

Armed with this knowledge, you should now be able to select the most critical assets for your site and prioritize them accordingly. If you want to further refine your priorities and speed, follow this checklist:

  • Enable the Priority column of Chrome Developer Tools.
  • Minimize the number of critical requests required.
  • Which requests to checkMust beEmitted before the user sees a fully rendered page. use<link rel="preload" />Prioritize these critical requests.
  • Optimize the resource that may be used in the next navigation using Link prefetching.
  • Use Link Preload HTTP Headers to declare resources to be preloaded before the HTML is fully delivered.
  • Make sure the image dimensions are properly written in advance.
  • Use inline SVG to display logos and ICONS.
  • Use better image formats such as AVIF or WEBP.
  • usefont-display: swapDisplay the text in the initial rendering.
  • Use a compressed font format such as WOFF2 or variable fonts.
  • View Chrome web events in Chrome://net-internals/# Events.
  • Remember: the fastest request is the one never made.

I wish you a happy optimization!