webpack——传输性能优化

111 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

webpack——传输性能优化

分包策略

手动分包

分包是将我们打包的代码块进行分离,将公共代码进行抽取,减少代码体积。

  ```js
  // a.js
  import _ from "lodash";

  console.log(_.join(["Another", "module", "loader"]));
  ```

  ```js
  // b.js
  import _ from "lodash";

  console.log(_.join(["Another", "module", "loader"]));
  ```

上面我们在a.jsb.js当中都引入了引入了lodash库,那么在进行打包的时候,webpack 会对这两个模块当中的lodash都进行依赖打包,这样打包后和chunk都包含了一部分公共的代码,现在我们要做的就是将这两个chunk当中的lodash代码单独抽离出来。

  ```JavaScript
  const path = require('path');
  const webpack = require('webpack');
  const HTMLWebpackPlugin = require('html-webpack-plugin');

  module.exports = {
    entry:{
      a:'./src/a.js',
      b:'./src/b.js'
    },

    plugin:[
      new webpack.optimize.CommonsChunkPlugin({
        name: 'common' // 指定公共 bundle 的名称。
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  }
  ```

在上面的配置当中,我们使用了插件CommonsChunkPlugin,它可以删除分离后的重复依赖,需要注意的是,CommonsChunkPlugin 插件将 lodash 分离到单独的 chunk,并且将其从 main bundle 中移除,减轻了大小。

自动分包

不同于手动分包,自动分包是从更实际的角度出发,从一个更宏观的角度来控制分包,而一般不对具体哪个包要分出去进行控制。因此使用自动分包,不仅非常方便,而且更加贴合实际的开发需求。要控制自动分包,关键要配置一个合理的分包策略。有了分包策略之后,不需要额外安装任何插件,webpack 会自动的按照策略进行分包。

实际上,webpack 在内部是使用 SplitChunksPlugin 进行分包的 过去有一个库 CommonsChunkPlugin 也可以实现分包,不过由于该库某些地方并不完善,到了 webpack4 之后,已被 SplitChunksPlugin 取代。

COoEZ.png

  ```JavaScript
  module.exports = {
    optimization:{
      splitChunks:{
        // 分包策略
      }
    }
  }
  ```

事实上,分包策略有其默认的配置,我们只需要稍微的改动就好了:

动态导入

当我们的项目需要进行动态代码拆分的时候,我们需要使用到 webpack 提供的两个技术:第一种就是使用 ES6 提供的import()来进行动态导入,而第二种则是使用 webpack 为我们提供的require.ensure来实现。 import()会返回一个promise,我们可以使用then来获取成功的回调。

首先我们需要修改一下 webpack 的配置

  ```JavaScript
  const path = require('path');
  const HTMLWebpackPlugin = require('html-webpack-plugin');

  module.exports = {
    entry:{
      index:'./src/a.js'   //入口文件
    },
    output:{
      filename:'[name].bundle.js',
      chunkFilename: '[name].bundle.js',   // 这里使用了 chunkFilename,它决定非入口 chunk 的名称。
      path: path.resolve(__dirname, 'dist')
    }
  }
  ```

  ```js 
  import(/* webpackChunkName: "lodash" */ "./lodash.js").then((_) => {
    console.log(_.join(["Another", "module", "loader"]));
  });
  ```

上面的代码当中,我们通过import()来引入lodash库,在进行构建的首,它会单独的分出一个bundle,并且我们这里使用了/* webpackChunkName: "lodash" */来指定我们的 bundle 名。

在开发当中,我们推荐使用第一种方式import()来进行动态的模块分离。