This is the 30th day of my participation in the More Text Challenge. For more details, see more text Challenge

background

One of the most important aspects of achieving high performance applications is to allow the user to load only the necessary resources at a time as much as possible, and use techniques such as lazy loading to acquire the resources that are not too high priority gradually, so that the first screen speed of the page is guaranteed. Code sharding is a technology unique to the WebPCK packaging tool that allows you to split code in a specific form so that users don’t have to load it all at once, but load it on demand.

CommonsChunkPlugin

Although this plugin is no longer recommended for use in webpack4, it’s worth looking at. This plug-in can extract the common parts of multiple chunks. Common module extraction can bring several benefits to several projects:

  • In the development process, the repeated module packaging is reduced and the development speed can be improved.
  • Reduce the overall resource volume;
  • Properly sharded code can make more efficient use of client-side caching.

The default rule for the plugin is that a module will be extracted if it is used by both entry chunks. For example, if a and B use React, react will be extracted. But it still has some shortcomings:

  1. A CommonChunkPlugin can only extract one vendor. If we want to extract multiple vendors, we need to configure multiple plug-ins, which adds a lot of duplicated configuration code.
  2. Mainfest, which we mentioned earlier, actually loads an extra resource for the browser, which is not speed friendly.
  3. Due to some internal design flaws, CommonChunkPlugin breaks the dependencies of modules in the chunk when extracting a common module, making it difficult to optimize more.

splitChunks

This is a new addition to WebPack. The code sharding feature is redesigned and implemented to improve CommonChunkPlugin, which is not only more powerful than CommonChunkPlugin but also easier to use. The following code

module.exports = {
    entry: './foo.js'.output: {
        filename: 'foo.js'.publicPath: '/dist/'
    },
    mode: 'development'.optimization: {
        splitChunks: {
            chunks: 'all',}}}// foo.js
import React from 'react';
import('./bar.js');
document.write('foo.js', React.version);

// bar.js
import react from 'react';
console.log('bar.js', React.version);
Copy the code

SplitChunk extraction conditions by default:

  • The extracted chunk can be shared or from the node_modules directory. This is easy to understand, modules that are referenced multiple times or in node_modules tend to be general-purpose modules that are better suited to be extracted.
  • For example, if the size of the js chunk is larger than 30KB, and the size of the Css chunk is larger than 50KB, this is easy to understand. If the size of the js chunk is too small, the optimization effect will be modest.
  • During the on-demand loading process, the maximum number of concurrent requests for resources is less than or equal to 5. The on-demand loading refers to the loading of scripts by dynamically inserting script tags. We generally don’t want to load too many resources at the same time because each request costs to set up and release links, so the extracted rules only apply when there are few parallel requests.
  • On the first load, the maximum number of concurrent requests for resources is less than or equal to 3, similar to the previous one, except that the first page load tends to be more performance demanding, so the default threshold is lower.

configuration

SplitChunk: {chunks: 'async'.minSize: {
        javascript: 30000.style: 50000,},maxSize: 0.minChunks: 1.maxAsyncRequests: 5.maxInitialRequests: 3.automaticNameDelimiter: '~'.name: true.cacheGroups: {vendor: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10,},default: {
            minChunks: 2.priority: -20.reuseExistingChunk: true}}}Copy the code

Match the pattern

The values of chunks are async (default), initial, and all. Async extracts only asynchronous chunks, and initial applies only to the entry chunk. All enables both chunks at the same time (recommended).

Matching conditions

MaxAsyncRequests, and maxInitialRequests

named

The default is true, which means that the newly generated chunk can be automatically named based on non-cachegroups and scopes, separated by automaticNameDelimiter.

cacheGroup

Can be understood as the rules for separating chunks, and by default there are two rules: Vendors and Default. Vendors are used to extract eligible modules from all node_modules, and default is used for modules that are referenced multiple times. These rules can be added or changed, and to disable a rule, you can set it to false. When a module conforms to multiple cacheGroups, the priority item is used to determine the priority.

Load resources asynchronously

Asynchronous resource loading mainly solves the problem that when there are too many modules and the resource volume is too large, some modules that cannot be used temporarily can be loaded lazily. This allows the user to download as little resources as possible when the page is first rendered, and subsequent modules are not triggered to load until they are needed, so this is generally called on demand loading.

There are two methods of asynchronous loading in WebPack, import(starting with Webapck2) and require. Ensure (webapck1). The difference between import and ES6 module is that there is no top-level loading required; Because it is a simple function call, I will not elaborate on it.

conclusion

There are several ways to fragment code -CommonChunkPlugin or SplitChunks, as well as asynchronous resource loading. With these methods, you can effectively reduce the size of the resource, make better use of the cache, and give a more user-friendly experience.