When it comes to front-end performance optimization, we usually think of enabling compression to compress the resource file size. Or enabling browser caching can have the effect of optimizing resource loading speed with fewer HTTP requests, but these means mainly improve the loading speed when repeatedly accessing the same resources. By default, the browser will only load resources declared in HTML first. If it is not declared, the browser will not load the resource earlier. So is there any way to load the resources needed for a page ahead of time to optimize the first load speed?

Fortunately, with the advancement of web technology, modern browsers can now load the resources needed for a page in advance. Using the resource hint pseudo-directives prefetch and preload, you can tell the browser to load the resources in advance, thus shortening the (first) load speed of the site and optimizing page performance.

preload

A type of preloading, which declares a resource to be submitted for loading to the browser via a declaration that is executed immediately when the resource is actually used, so there is no need to wait for the network to be consumed.

There are three ways to use it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!-- Use link tags to statically mark resources that need to be preloaded -->
<link rel="preload" href="/path/to/style.css" as="style">

<!-- Create a link tag dynamically with a script and insert it into the head header -->
<script>
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'style';
link.href = '/path/to/style.css';
document.head.appendChild(link);
</script>

<!-- Add the preload field to the HTTP response header -->
Link: <https://example.com/other/styles.css>; rel=preload; as=style

rel attribute value is preload; as attribute is used to specify the type of the resource and set the Accep request header according to the resource type so that the corresponding resource can be requested using the normal policy; href is the address of the resource request; onload and onerror are the callback functions when the resource loads successfully and fails, respectively.

as values include: style, script, image, font, fetch, document, audio, video, etc. If you request a cross-domain resource, you need to add the crossorigin attribute.

1
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>

Features

  • preload does not block the windows onload event, unless the preload resource is requested from a resource that blocks the window load.
  • It is recommended to add the crossorigin attribute when requesting cross-domain resources, otherwise it may lead to secondary loading of resources (especially font resources).

Usage Scenarios

Loading fonts in advance

Fonts in the web are a type of resource that loads late, but their rendering is critical to the user experience. Slow loading can cause font jitter to the user, i.e. the font will be displayed as the environment default font first.

1
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>

Loading third-party js

For example, if you want to load a piece of code that counts page visits, but you don’t want the loading of this code to delay the rendering of the page and thus affect the user experience, you don’t want to delay the onload event of the window.

1
2
3
<link rel="preload" as="script" href="async_script.js"
    onload="var script = document.createElement('script'); 
    script.src = this.href; document.body.appendChild(script);">

Responsive loading

If the web side supports mobile browser access, the media property of the link can be used to determine when different resources are loaded on the web side and the mobile side. A common practice is to load resources dynamically by determining the current browser type through JS, but then the browser’s preloader will not be able to find them in time, which may delay the loading time and affect the user experience.

1
2
<link rel="preload" as="image" href="map.png" media="(max-width: 600px)">
<link rel="preload" as="script" href="map.js" media="(min-width: 601px)">

Predicting user behavior to load resources in advance

For example, if the user hovers over an item, such as a product. Analyze the resources needed for the product details page and enable preload loading in advance.

Compatibility

You can determine if preload is supported by the following method.

1
2
3
4
5
6
7
8
const isPreloadSupported = () => { 
  const link = document.createElement('link'); 
  const relList = link.relList; 
  if (!relList || !relList.supports) { 
    return false;  
  } 
  return relList.supports('preload'); 
};

preload gives priority to loading resources

The browser priority for loading resources is as follows.

preloads use “as” or use the “type” attribute to indicate the priority of the resource they are requesting (for example, a preload using the as=“style " attribute will get the highest priority). Requests without the “as” attribute are treated as asynchronous, with “Early” meaning that they are requested before all image requests that are not preloaded (“late” meaning after ).

The resource priority can be viewed in chrome at

Attention

Avoid abusing preload

If you are not sure that a resource is bound to be loaded, do not use preload incorrectly, as this will put the cart before the horse and burden the page with more work. When a preload loads a resource that is not used, the browser will warn that

preload adds the crossorigin attribute when loading cross-domain resources

1
2
<link rel="preload" as="font" href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff">
<link rel="preload" as="font" crossorigin href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff">

If a cross-domain file is preloaded without adding the crossorigin attribute, it will be requested twice.

prefetch

prefetch tells the browser about a resource that may be used in the future, such as the next page. The browser will then load the corresponding resource at leisure, or preload it if it can predict the user’s behavior, such as lazy loading, clicking on another page, etc. It is used in the same way as preload.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!-- Use link tags to statically mark resources that need to be preloaded -->
<link rel="prefetch" href="/path/to/style.css" as="style">

<!-- Create a link tag dynamically with a script and insert it into the head header -->
<script>
const link = document.createElement('link');
link.rel = 'prefetch';
link.as = 'style';
link.href = '/path/to/style.css';
document.head.appendChild(link);
</script>

<!-- Add the prefetch field to the HTTP response header -->
Link: <https://example.com/other/styles.css>; rel=prefetch; as=style

Compatibility

preload and prefetch vs

  1. Chrome has four types of caches: http cache, memory cache, Service Worker cache, and Push cache. both are stored in the http cache when a preload or prefetch resource is loaded. when the resource is loaded, if the resource is cacheable, it is stored If the resources are not cacheable, they are stored in the memory cache until they are used.
  2. Neither preload nor prefetch have same-domain restrictions.
  3. preload is mainly used to preload the resources needed for the current page; and prefetch is mainly used to load the resources that will be needed for future pages.
  4. prefetch will be cached on the network stack for at least 5 minutes, regardless of whether the resource is cacheable or not.
  5. preload requires the as attribute to specify a specific resource type so that the browser can assign a certain priority to it and load the resource correctly.

Avoid mixing preload and prefetch

Mixing preload and prefetch does not reuse resources, but reloads them.

1
2
<link rel="preload"   href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff" as="font">
<link rel="prefetch"  href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff" as="font"> 

preconnect

This includes DNS resolution, TLS negotiation, and TCP handshaking, which eliminates round-trip delays and saves the user time.

“Preconnect is an important tool for optimization that can reduce the round-trip path in many requests – in some cases by hundreds or thousands of milliseconds of latency.” – lya Grigorik (author of The Definitive Guide to Web Performance)

It is used in the same way as preload.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!-- Use link tags to statically mark resources that need to be preloaded -->
<link rel="preconnect" href="https://cdn.domain.com" as="style" crossorigin>

<!-- Create a link tag dynamically with a script and insert it into the head header -->
<script>
const link = document.createElement('link');
link.rel = 'preconnect';
link.as = 'style';
link.href = 'https://cdn.domain.com';
document.head.appendChild(link);
</script>

<!-- Add the preconnect field to the HTTP response header -->
Link: <https://cdn.domain.com>; rel=preconnect; as=style

Here is an example of using preconnect for Google Fonts. By adding a preconnect hint to fonts.gstatic.com, the browser will immediately initiate the request and execute it in parallel with the CSS request. In this scenario, preconnect eliminates three RTTs (Round-Trip Time) from the critical path and reduces latency by more than half a second, as analyzed in more detail in lya Grigorik’s eliminating RTTS with preconnect.

1
2
<link href='https://fonts.gstatic.com' rel='preconnect' crossorigin>
<link href='https://fonts.googleapis.com/css?family=Roboto+Slab:700|Open+Sans' rel='stylesheet'>

You can see a time saving of about 400ms on the second request.

Compatibility

Cases

  1. Housing.com saw an approximate 10% reduction in interactivity time when switching to proload for their progressive web application scripts

  2. Shopify got a 50% (1.2s) text rendering optimization on Chrome Desktop after switching to preload loading fonts, which completely solved their text flicker problem.

  3. When the Financial Times used the preload HTTP header on their site, they saved about 1s of time in displaying the header image.

Summary

preload, prefetch and preconnect allow the browser to load the required resources in advance, separating the download and execution of the resources, which can bring a significant improvement to the first screen rendering if used properly and can bring the ultimate experience to the page interaction.


Reference https://blog.dteam.top/posts/2021-08/web-performance-preload-prefetch-preconnect.html