In a recent project, a pre-loading of chunks was attempted to improve the performance of the chunks. Although the asynchronous loading process is done, the size of the project determines that there are still multiple asynchronous chunk.js to be preloaded, which I refer to as preload and prefetch.

Here is a plugin from GoogleChromeLabs: preload-webpack-plugin.

A webpack plugin for injecting <link rel=’preload|prefecth’> into HtmlWebpackPlugin pages, with async chunk support




Usage is generally as follows, refer to its documentation for details:

config = rewirePreloadPlugin(config, env, {  
  rel: 'preload',  
  include: 'initial',  
  as(entry) {    
    if (/\.(css|less)$/.test(entry)) return 'style';    
    if (/\.woff$/.test(entry)) return 'font';    
    if (/\.(png|jpg|jpeg|svg)$/.test(entry)) return 'image';    
    return 'script';  
  }});
Copy the code

This plugin automatically adds cross-domain to font elements (WOFF) :

Source:

const crossOrigin = asValue === 'font' ? 'crossorigin="crossorigin" ' : ' ';

filesToInclude+= `<link rel="${options.rel}" as="${asValue}" ${crossOrigin}href="${entry}">\n`Copy the code

After use:



Will add a bunch of to your Head tag in index.html

This means that these resources are preloaded and fetched from the cache. Will improve the efficiency of web page opening, but abuse will also waste bandwidth.

In practice, there is a problem with create-react-app and no eject. The current mode for preload includes: ‘initial’ | ‘allChunks’ |’ asyncChunks’ | ‘allAssets | [‘ chunkName], (ps: Initial mode is also a great PR for Rain Creek and provides black-and-white lists, which should be said to be very fine-grained control over how we set files to preload on demand.

But there are actually files set that I don’t need preload for, which is wasteful.

Preload and Prefetch

appears earlier, browser support is good, popular understanding is to focus on the next page resource preload, so the current page priority is very low.

Prefetch downloads or prefetches documents that the user is likely to access in the near future while the browser is idle, prefetches resources into the cache after the current page is loaded, and later calls are fetched directly from the cache, thus improving performance.

is now. The browser encounters a rel= ‘preload’ tag and pushes it into the preloader, which will also be used for any other resources of any kind that we need. To complete the basic configuration, you also need to specify the resource path and type of the resource to be preloaded using the href and as attributes.

To quote a passage from MDN:

<link>Elements of the
relAttribute value of an attribute
preloadAllows you to use your HTML pages
<head>The element contains declarative resource requests that specify which resources are needed immediately after the page loads. For this immediate-need resource, you may want to acquire it early in the page loading lifecycle, preloading it before the browser’s main rendering mechanism kicks in. This mechanism allows resources to be loaded and available earlier and is less likely to block the initial rendering of the page, thus improving performance. This article provides an example of how to use it effectively
preloadBasic explanation of the mechanism


It is characterized by declarative resource fetch requests, non-blocking onLoad, and fine-grained control provided by AS

To summarize its advantages:

  1. Optimize resource loading priorities more precisely, which ensures that resources are loaded in order of importance.
  2. Match future loading requirements and reuse the same resource where appropriate (same resource).
  3. Apply the correct content security policy for the resource.
  4. Set the correct Accept request header for the resource.

Note: Ignoring the AS attribute, or the wrong AS attribute, makes preload equivalent to an XHR request, and the browser does not know what is being loaded and therefore gives such resources a very low load priority.

Preload also supports onLoad completion callbacks, MIME, cross-domain fetching, reactive preloading, scripted loading, and more, see MDN, here, and here.

The cache

Since both Preload and Prefetch fetch resources from the HTTP cache first, we must be exposed to many 304 Not Modified responses.

Let’s start with a 304 response:



The two most important headers in 304 are if-none-match and if-modified-since.

The value of the former is the ETag returned in the last response. The ETag is a unique identification of the resource and is regenerated whenever the resource changes. The server receives if-none-match in the request header and compares it with the Etag of the file resource. If it is the same, the resource has Not changed, and returns 304 Not Modified with no response body. When a 304 response is received, the client reads the corresponding resource from the cache. If the resource is different, it indicates that the resource has changed. Then the server returns an HTTP/200 OK response with the latest content of the resource. When the client receives the 200 response, it overwrites the old cache resource with the new response body.

The latter corresponds to last-Modified returned from the previous response. Last-modified is when the resource file was Last Modified. The server returns the response header, and the browser saves the value so that the next time it sends a request, In the if-modified-since field in the request header, the server will also compare the receipt and return 304 If it has not expired or 200 OK If it has expired. Old files will also be updated.

If the requests for that resource, both of which come without a unconditionally attached head, the servers must return the complete resource data.

The headers described above are the key players in negotiating the cache.

The concept of conditional requests is that there is no way to determine whether the front-end cache resource is up to date, so use the above header to do a validation and return 304 or 200. We can save a response body by making a conditional request, but the request is sent anyway.

What if you don’t even want to make a request here?

Strong cache, negotiated cache

There are two main types of browser caches: negotiated cache and full cache, as well as so-called negotiated cache and strong cache.

1. Strong cache: it does not send a request to the server, but reads resources directly from the cache. In the Network option of the Chrome console, you can see that the request returns a status code of 200.

2. Negotiation cache: sends a request to the server. The server will judge whether the negotiation cache is matched according to some parameters of the request header.

What they have in common is that they both read resources from the client cache; The difference is that strong caches don’t make requests, negotiated caches do.

Browser cache flowchart:



So we can skip sending requests by setting Expires(HTTP1.0) and cache-Control (HTTP1.1) to hit strong caches.

Expires: The expiration time in the response header. If the browser reloads the resource within this expiration time, the strong cache will be hit.

Cache-control: when max-age= 600, it means that the strong Cache will be hit if the resource is reloaded within 10 minutes of the correct return time of the request, which is also recorded by the browser.

Control of the browser cache by user actions:

  1. F5 refresh, the browser sets max-age to 0, skips strong cache judgment, and implements negotiation cache judgment.
  2. Ctrl + F5, skip negotiation cache and strong cache and pull resources directly from the server.
  3. It is a normal user behavior to access the address bar and redirect links, which triggers the browser cache mechanism.

To be continued….