Packaging optimization practice (how to code spliting)

Packaging optimization practice (how to code spliting)

Use the webpack plugin to find out which packages take up a lot of space

In the development environment, you can use analyze-webpack-plugin to observe the occupancy of each module. In this project, for example: browser enter http://localhost:3000/analyze.htmlmay see the following results:

Load on demand

  • On-demand loading of modules combined with babel ;
  • Test day.js instead of moment.js. In fact, moment.js also uses on-demand loading (the experiment is reduced by 40KB+), so the final result is not much different;

code-spliting

Use MiniCssExtractPlugin to separate JavaScript and Css files:

  823.94 KB           build/static/js/main.496a38b7.js
  8.2 KB              build/static/css/main.css
 

Code-spliting officially gives three schemes, which are as follows:

Option 1: Add a package entry at the entry

The disadvantages of Option One are as follows:

  • If multiple files introduce the same package (such as lodash), the referenced package will be packaged twice;
  • This scheme is not flexible enough to dynamically split the code according to logic;

Therefore, Option One is usually combined with Option Two and Option Three. The configuration of Option One is roughly as follows:

entry: [require.resolve('./polyfills'), paths.appIndexJs],

//can also be written as

entry: {
  polyfill: require.resolve('./polyfills'),
  IndexJs: paths.appIndexJs,
},

Option 2: Use plug-ins SplitChunkPlugin

  optimization: {
    runtimeChunk: false,
    splitChunks: {
      cacheGroups: {
        vendor: {
          chunks:'all',
          test:/[\\/]node_modules[\\/]/,
          name:'vendor',
          maxAsyncRequests: 5,
          priority: 10,
          enforce: true,
        },
      },
    },
  },

The packaging effect is as follows:

  723.96 KB  build/static/js/vendor.a9289a29.chunk.js//node-modules  
  98.72 KB   build/static/js/main.7bcaca24.js
  8.2 KB     build/static/css/1.css
 

At this time, the packages in node-modules are packaged into one big block, which is still unfriendly to loading. The solution is: package the core framework separately, and load the remaining modules asynchronously. For example, you can use bundle-loader ).

  optimization: {
    runtimeChunk: false,
    splitChunks: {
      cacheGroups: {
        vendor1: {// 
          chunks: 'all',
          test:/[\\/]node_modules[\\/](react|react-dom|antd)[\\/]/,
          name: 'vendor1',
          maxAsyncRequests: 5,
          priority: 10,
          enforce: true,
        },
        vendor2: {// 
          chunks: 'all',
          test:/[\\/]node_modules[\\/]/,
          name: 'vendor2',
          maxAsyncRequests: 5,
          priority: 9,
          enforce: true,
          reuseExistingChunk: true,
        },
      },
    },
  }
 

The packaging effect is as follows:

  588.06 KB  build/static/js/vendor2.d63694f4.chunk.js
  133.17 KB  build/static/js/vendor1.0d40234c.chunk.js
  98.72 KB   build/static/js/main.b7a98d03.js
  8.2 KB     build/static/css/2.css
 

You can see that the node_modules package has been split into core modules and non-core modules at this time.

Use dynamic introduction syntax import()

1. use the react-loadable package of Amway on the official website . Its idea is (instead of modules) to dynamically segment the code and asynchronously load the required components, thereby greatly improving the page loading rate.

Perform the following configuration on the routing interface:

const Loading = () => <div>Loading...</div>

const Home = Loadable({
  loader: () => import('../pages/home'),
  loading: Loading,
})

//Use routing like this
<Router>
  <Route path="/home" component={Home}/>
  <Route path="/follow" component={Follow}/>
  <Route path="/tools" component={Tools}/>
  <Route path="/music" component={Music}/>
  <Route path="/todo" component={Todo}/>
  <Route path="/album" component={Album}/>
  <Route path="/editor" component={Editor}/>
  <Route path="/todoList" component={TodoList}/>
  <Route path="/searchEngine" component={Search}/>
  <Route path="/waterfall" component={Waterfall}/
</Router>

Let's look at the results after code splitting:

The test results here are carried out after removing the configuration of the second scheme. After the experimental comparison, the method of using the third scheme is slightly better than the way of using the second and third schemes together.

  235.89 KB  build/static/js/IndexJs.57ee1596.js
  225.94 KB  build/static/js/15.c09a5919.chunk.js
  138.18 KB  build/static/js/17.30c26142.chunk.js
  82.71 KB   build/static/js/1.667779a6.chunk.js
  57.55 KB   build/static/js/16.f8fa2302.chunk.js
  16.46 KB   build/static/js/2.e7b77a5d.chunk.js
  14.79 KB   build/static/js/18.cad1f84d.chunk.js
  12.51 KB   build/static/js/0.73df11a7.chunk.js
  11.22 KB   build/static/js/13.19501c58.chunk.js
  8.34 KB    build/static/js/5.33fd1c35.chunk.js
  7 KB       build/static/js/8.9f1d0a47.chunk.js
  5.86 KB    build/static/js/12.24f0a7ec.chunk.js
  5.06 KB    build/static/css/18.css
  4.97 KB    build/static/js/polyfill.1c61a660.js
  3.58 KB    build/static/js/7.dd4976e3.chunk.js
  3.53 KB    build/static/js/14.16f6b811.chunk.js
  3.42 KB    build/static/css/17.css
  2.98 KB    build/static/js/10.464a61e4.chunk.js
  2.02 KB    build/static/js/11.3728d5a9.chunk.js
  1.45 KB    build/static/js/6.92fbac58.chunk.js
  1.13 KB    build/static/js/9.59160a3a.chunk.js
 

How many routes there are, the react-loadable library automatically splits up how many package files for us. It is conceivable that the bigger the project, the more obvious the benefits of such a dynamic library.

And it can be clearly seen that when we are under/home, only the home component is loaded, and other components are not loaded!

So mysterious force react-loadable is how to achieve it, it is essentially a higher-order functions using the property broker, by incorporating higher-order function Lane import()added to the various states, so as to achieve asynchronous loading modules.

references

code-splitting
Code-Splitting(react)