📜 ⬆️ ⬇️

Prefetch and preload webpack directives

In webpack 4.6.0. support for the prefetch and preload directives has preload (they look, respectively, as the “magic comments” of webpackPrefetch and webpackPreload to import() commands). With their help, the browser can give hints about resources that the user may need in the near future. The browser loads such resources in advance, which allows the user to improve the experience of working with the site.

image

In the material, the translation of which we are publishing today, we will discuss how to use these guidelines to optimize the performance of websites.

What is <link rel = "prefetch">?


The prefetch directive tells the browser that the specified resource may be needed in the future to navigate the site.
')
Browsers usually download similar resources at a time when they are not busy with other tasks. After downloading, the resulting resource is in the HTTP cache, ready to use when processing future requests. If you need to organize a preliminary receipt of a set of resources, such requests are queued, they are executed when the browser is in idle mode. Coming out of this mode, the browser can interrupt the current download of the prefetch resource (and place a partial result in the cache in order to return to its loading later using Content-Range headers) and stop the prefetch request processing queue.

As a result, we can say that using the prefetch resource hint causes the corresponding resources to be loaded when the browser is idle.

What is <link rel = "preload">?


The preload directive informs the browser that the resource marked by it will definitely be needed in this session of working with the site, but it will be accessed a little later. At the same time, Chrome even displays a warning when a similar resource is not used 3 seconds after the download.

Usually browsers load such resources, giving them an average priority (such loading does not block the user interface).

Resources with the preload hint are loaded as normal resources, however, their loading starts a little before the user accesses them.

The benefits of prefetch and preload directives


The preload directive allows preload to load resources that will be needed soon and avoid the “waterfall effect”, when everything you need to display a page starts loading immediately after clicking on the appropriate link. This technology allows you to split the page loading into two stages, when you first load the HTML code, and then everything else. At the same time, this does not mean additional load on the network channel.

The prefetch used during browser downtime to speed up future interactions with the site. Its use may mean the need for additional traffic costs in the event that the user does not use the downloaded resources.

Code separation


Here it is assumed that we are talking about a huge application prepared by means of webpack using the on-demand download mechanism ( import() command) to download only those parts of the application that the user currently needs.

As an example, we will look at the home page ( HomePage ), which has a login button ( LoginButton ), which opens a modal window for entering credentials ( LoginModal ). After the user logs in, he is shown the DashboardPage page. On this page there may be other buttons needed to go to other pages, but we focus on the fact that the goal of the user is this page.

In order to achieve the best performance, there is an import("LoginModal") command on the page with a login button, and an import("DashboardPage") command on the page for entering credentials.

Now it turns out that our experimental application is divided into at least three parts: the home page, the login page, and the control panel page. Upon initial download, you only need to show the user the home page. It loads quickly, which gives us the full right to expect that the user will have good impressions from working with this page. However, when the user clicks on the login button, he will notice some delay required to display the login window, since this part of the application still needs to be loaded before the user sees this window. The same goes for the control panel page. At this stage, we have a question about how to improve the user experience of working with the site.

Using prefetch hints in webpack


Due to the fact that now in the webpack, you can use prefetch hints, we can improve the above scenario of working with the site. Make it very easy. Namely, it is necessary, on the page with the login button, to use, instead of the import("LoginModal") command import("LoginModal") , the import(/* webpackPrefetch: true */ "LoginModal") command import(/* webpackPrefetch: true */ "LoginModal") . Similarly, on the page for entering credentials, instead of the import("DashboardPage") command import("DashboardPage") you need to use the import(/* webpackPrefetch: true */ "DashboardPage") construction import(/* webpackPrefetch: true */ "DashboardPage") .

These commands will tell the webpack that it should load, after loading the main page (when the browser is idle) the specified fragments of the application. In this example, after loading the home page, the loading of the login page is added to the queue. And when the download of the login page is complete (the actual download, not the preliminary one, caused by the webpackPrefetch hint), a fragment of the application representing the control panel page will be put in the download queue.

Based on the fact that the entry point to the application is the home page, on the basis of the above commands, an link like <link rel="prefetch" href="login-chunk.js"> will be formed on the HTML page. The application fragment representing the login page is loaded on demand, so webpack will take care to embed a tag like <link rel="prefetch" href="dashboard-chunk.js"> into the page after the login page is loaded .

This will positively affect the user experience of working with the site. Namely, here it will be possible to note the following improvements:


Please note that above we have described the ideal scenario.

The user will not always see the pages that are supposed to be loaded in the background instantly. There are many factors that can affect this. Among them are slow Internet connections, users who very quickly click on the corresponding buttons, disabled prefetch processing on devices that are focused on saving traffic, the lack of support for this feature in browsers, very slow processing of downloadable site pages and so on.

Using preload-tips in webpack


Above, we talked about the import(/* webpackPrefetch: true */ "...") construct import(/* webpackPrefetch: true */ "...") to describe the resources that are supposed to be loaded when the browser is idle. There is a similar command, import(/* webpackPreload: true */ "...") , to describe the preload resources. If you compare these two approaches, you can identify many differences:


As a result, prefetch hints are rarely used. For example, they may be needed if the module immediately imports something with the import() command. This may make sense if, for example, a component depends on a large library, which must be present in a separate fragment of the application. For example, the chart output component, ChartComponent , uses a large chart library - ChartingLibrary . The component, during the download, shows the download indicator ( LoadingIndicator ) and immediately executes the import(/* webpackPreload: true */ "ChartingLibrary") command import(/* webpackPreload: true */ "ChartingLibrary") . As a result, when loading a page that uses a ChartComponent is requested, it is requested using the <link rel="preload"> , and loading a fragment of the application with the library. Assuming that the page with the component is smaller than the application fragment with the library and its loading is completed faster, this page will appear with the loading indicator, which will be displayed until the download of the application fragment with the library is completed. This will slightly reduce the load time for everything needed, since the system performs loading in parallel, without breaking this process into two separate actions. This will be especially noticeable where network connections are characterized by high latency.

It must be said that improper use of the webpackPreload design can degrade performance, so you need to use it carefully.

If you are thinking about what kind of mechanism you need - preload or prefetch , you will probably be better off using prefetch . In this case, the above is true for the import() webpack command. On ordinary HTML pages, preload probably more suitable for preload .

Loading multiple prefetch resources


If necessary, the page can use any number of import() commands with the directive webpackPrefetch . However, it should be borne in mind that all resources loaded in this way will fight for bandwidth.

Corresponding requests are queued, which can lead to a situation where the fragment necessary to service the user's request turns out to be not loaded to the right moment.

This is not a big problem if all the prefetch resources are needed with the same probability. However, if some resources are more important than others, then, most likely, it is worth thinking about the possibility of controlling the order of loading resources.

Fortunately, this is possible, although this goes beyond the basic use of prefetch and preload .

So, instead of using the webpackPrefetch: true construct, you can, instead of a boolean value, use a number. As a result, the webpack will load the fragments in the specified order. For example, a resource with webpackPrefetch: 42 will be loaded before a resource with webpackPrefetch: 1 , which, in turn, will be loaded before the resource with webpackPrefetch: true , and this resource will be loaded to the resource with webpackPrefetch: -99999 (this looks like z-order ) . In fact, true here is the same as 0.

Similarly, you can work with webpackPreload , but you hardly need it.

Frequently asked Questions



The preload directive takes precedence over prefetch , and prefetch used if there are no other instructions for a specific webpack resource. If several commands are used to preload the same resource, the one with higher priority is activated.


In this situation, the browser ignores these prompts, and the webpack will not make an attempt to use some kind of backup mechanism. In fact, it’s not by chance that prefetch and preload are called “prompts”, so even if the browser supports them, it can, for some reason, ignore them.


The webpack runtime only accepts prefetch and preload for resources loaded on demand. When prefetch or preload are used in import() commands in site fragments that are input points, the HTML generation system is responsible for adding the <link> tags to the resulting code.

Relevant reference data is available at entrypoints[].childAssets .


This will lead to irrational use of the bandwidth of the Internet channel. In addition, more value can be gained from selectively applying these directives for import() commands related to the resources a user will need with a high degree of probability. It is not necessary to load Internet channels in vain, because for some users they are far from unlimited. Therefore, use these directives only when they are really needed.


The corresponding code in the webpack runtime is added only if the prefetch and preload are used to work with materials that are loaded on demand. As a result, if you do not use this opportunity, no additional load on the system is created.


Yes it is possible. Comments should either be separated by a comma, or simply use several separate comments:

 import( /* webpackChunkName: "test", webpackPrefetch: true */ "LoginModal" ) //  import( /* webpackChunkName: "test" */ /* webpackPrefetch: true */ "LoginModal" ) //    


Yes, you can add webpack's “magic comments” to the import() command and rollup will save them. If the finished project is collected using a webpack, it will take advantage of these comments. If the webpack will not be used, they will simply be removed by the minifier.


Best of all is to measure performance using the A / B testing methodology. When applied to such a situation, it is impossible to give unambiguous universal advice. It depends on the likelihood that the user will need to visit some part of the application.


It depends on the application. In general, such service workers load all application resources without worrying about the order in which the download is performed. At the same time, the prefetch directives allow you to specify the order of loading resources, they depend on the location in the application in which the user is located. In addition, the prefetch mechanism is more cost-effective for bandwidth and loads data only when the browser is idle.

Measure the time required to fully load an application using a low-speed communication channel; compare this with when the user needs to make the first transition in the application. If the application is very large, it makes sense to consider using the prefetch , rather than caching the entire application in one go.


Yes, vital resources can be placed at the entry point into the application, and minor ones can be loaded using import() with webpackPreload: true . And do not forget to add <link rel="preload"> for the resources necessary for the application entry point to work properly (before the tags for the children).

Results


In this article, we talked about the webpack innovation, which allows the use of prefetch and preload . Their correct application helps to improve the user experience of working with the site, and the wrong can lead to unnecessary costs of traffic, which is especially important for cases when working with a web resource is conducted on a device whose capabilities are limited. We hope the new webpack features will come in handy for you in creating quick and convenient web projects.

Dear readers! Do you see practical situations in which the prefetch and preload directives can be useful to you?

Source: https://habr.com/ru/post/354188/


All Articles