初级分析

stats

  • 使用webpack 内置的stats
  • 配置 package.json

    1. "scripts": {
    2. "build:stats": "webpack --config webpack.prod.js --json > stats.json",
    3. },

    缺点

  • 只能大体的看出,构建速度和每个模块的体积,但是具体怎么处理无法分析出来

    速度分析

  • 使用 speed-measure-webpack-plugin 可以看到每个 loader 和 每个插件的耗时

    1. npm install --save-dev speed-measure-webpack-plugin

    webpack 配置 ```javascript const SpeedMeasurePlugin = require(“speed-measure-webpack-plugin”);

const smp = new SpeedMeasurePlugin();

const webpackConfig = smp.wrap({ plugins: [new MyPlugin(), new MyOtherPlugin()], });

  1. <a name="EFo1e"></a>
  2. #### 结果如下
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12492651/1630502767135-5cc752f5-fc8a-47b2-bc9a-6aeb4a40ee34.png#clientId=uec793f8a-774f-4&from=paste&height=332&id=u5022b9fa&margin=%5Bobject%20Object%5D&name=image.png&originHeight=664&originWidth=702&originalType=binary&ratio=1&size=430235&status=done&style=none&taskId=u93c62acd-0ae0-4cde-9aad-befc0f44253&width=351)
  4. <a name="pQDJK"></a>
  5. ### 体积分析
  6. - 使用 webpack-bundle-analyzer 分析体积
  7. - 构建完成后 会在8888 端口展示大小
  8. <a name="kvQ7F"></a>
  9. #### 可以分析那些问题
  10. - 依赖的第三方模块文件大小
  11. - 比如 jsonEditor 没必要全部引入
  12. - 业务中组件代码大小
  13. <a name="H5Vjs"></a>
  14. #### 使用
  15. ```javascript
  16. npm install --save-dev webpack-bundle-analyzer

使用高版本的webpack 和 nodejs

  • webpack 3 和 4 构建速度对比

         ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12492651/1630503731598-3b954166-b6d6-4418-8490-e2a74cef9482.png#clientId=uec793f8a-774f-4&from=paste&height=189&id=u00d53353&margin=%5Bobject%20Object%5D&name=image.png&originHeight=530&originWidth=1588&originalType=binary&ratio=1&size=633025&status=done&style=none&taskId=u136ba462-fbe1-4a9a-a3f1-8dba05c0c23&width=566)
    

    webpack4 优化方面

  • V8 带来的优化 (各种语法)

  • 默认使用更快的 MD4 HASH 算法
  • 使用字符串方法替代正则表达式

    多进程 | 多实例 构建

    可选方案

  • parallel-webpack

  • HappyPack
  • thread-loader (官方)

    thread-loader (官方)

  • 和 HappyPack 原理一样,维护一个线程池,每次webpack解析一个模块,thread-loader 会将它以及它的依赖分配给 worker 线程中

webpack 配置

 use: [
   {
     loader: 'thread-loader',
     options: {
       workers: 3,
     }
   },
   'babel-loader'
 ], //使用的loader

并行压缩

方案

  • webpack 3
    • 使用 parallel-uglify-plugin 和 uglifyjs-wbpack-plugin
  • webpack 4

    • 使用 terser-webpack-plugin (官方使用 推荐)

      terser-webpack-plugin 使用

      npm install terser-webpack-plugin
      
      webpack 配置
      optimization: {
      minimize: true,
      minimizer: [
      new TerserPlugin({
       parallel: 4,
      }),
      ],
      },
      

      进一步分包

      HtmlWebpackExternalsPlugin 缺点

  • 如果库很多,则要引入 一堆 script 标签

    /**基础包分离 CDN 引入 */
    new HtmlWebpackExternalsPlugin({
    externals: [
      {
        module: 'react',
        entry: 'https://now8.gtimg.com/now/lib/16.2.0/react.min.js',
        global: 'React',
      },
      {
        module: 'react-dom',
        entry: 'https://now8.gtimg.com/now/lib/16.2.0/react-dom.min.js',
        global: 'ReactDom',
      }
    ]
    })
    

    splitChunks 缺点

  • 会影响 整个项目的构建

    optimization: {
      splitChunks: { 
        cacheGroups: {                // 缓存组会继承splitChunks的配置,但是test、priorty和reuseExistingChunk只能用于配置缓存组。
          vendor: {                   // key 为entry中定义的 入口名称
            chunks: "all",        // 必须三选一: "initial"(初始化) | "all" | "async"(默认就是异步)
            test: /(react|react-dom)/,     // 正则规则验证,如果符合就提取 chunk
            name: "vendor",           // 要缓存的 分隔出来的 chunk 名称
            // minSize: 0,
            // minChunks: 1,
          }
        }
      }
    }
    

    最终方案

  • 使用预编译资源模块 DLLPlugin 进行分包,DllReferencePlugin 对 manifest.json 引用

  • 将 react react-dom redux react-redux 基础包和业务包打包成一个文件

image.png
image.png

利用缓存提升二次构建速度

babel-loader开启缓存

  • 利用 HappyPack 插件,配置babel-loade缓存

    terser-webpack-plugin 开启缓存

    minimizer: [
    new TerserPlugin({
      parallel: true,
      cache: true
    })
    ],
    

    cache-loader 或者 hard-source-weback-plugin

  • 直接引入到 plugin 即可

    npm i hard-source-weback-plugin@0.13.1 -D
    

    缩小构建目标

  • 目的 尽可能少的构建模块

  • 比如 babel-loader 不解析 node_modules

    rules: [
    {
    test: /\.(js|jsx)$/, //匹配规则
    use: [
      'babel-loader'
    ], //使用的loader
    exclude: /(node_modules)/,//排除资源
    },
    ]
    

    减少文件的搜索范围

  • 配置 resolve

    resolve: {
      alias: {
          'react': path.resolve(__dirname, './node_modules/xxx/xx.js')
      },
      mainFields: ['browser', 'main'],
      // 当引入的文件缺少后缀名时:优先查找 .js 然后 .json 文件
      extensions: ['.js', '.json'],
      // 默认去 node_modules 下找第三方模块
      modules:[path.resolve(__dirname, 'node_modules')]
    }
    

    tree shaking 擦除CSS

  • 减少不必要的js 和 css 文件

  • 使用 purgecss-webpack-plugin 必须和mini-css-extract-plugin 配合使用
    npm i purgecss-webpack-plugin -D
    
    ```sql const path = require(‘path’) const glob = require(‘glob’) const MiniCssExtractPlugin = require(‘mini-css-extract-plugin’) const PurgeCSSPlugin = require(‘purgecss-webpack-plugin’)

new PurgeCSSPlugin({ paths: glob.sync(${PATHS.src}/**/*, { nodir: true }), })

<a name="jqPMW"></a>
### 图片压缩

- 使用 image-webpack-loader
```javascript
npm i image-webpack-loader@5.0.0 -D