• webpack打包优化


     

     打包分析

     

    1.初级分析:webpack内置的stats(构建的统计信息)

    可以在 package.json 中使用 stats,也可以在 Node API 中使用 stats

    webpack --config webpack.prod.js --json > stats.json

     

    2.速度分析:speed-measure-webpack-plugin (分析整个打包总耗时&每个插件和loader的耗时情况)

     const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
    
     const smp = new SpeedMeasurePlugin();
    
     const webpackConfig = smp.wrap({
       plugins: [
         new MyPlugin(),
         new MyOtherPlugin()
       ]
     });

     

    3.体积分析:webpack-bundle-analyzer(分析依赖的第三方模块文件和业务里面的组件代码大小)

    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
     
     module.exports = {
       plugins: [
         new BundleAnalyzerPlugin()
       ]
     }

     

    速度优化

     

    1.使用高版本的webpack

    webpack4 增加了一个叫mode的配置项

    production默认值会提供一系列有效的默认值以便部署应用

    optimization.splitChunks总是启用

     

    2.多进程构建

    happypack 每次 webapck 解析一个模块,HappyPack 会将它及它的依赖分配给 worker 线程中

     exports.plugins = [
        new HappyPack({
          id: 'jsx',
          threads: 4,
          loaders: [ 'babel-loader' ]
        }),
        new HappyPack({
          id: 'styles',
          threads: 2,
          loaders: [ 'style-loader', 'css-loader', 'less-loader' ]
        })
      ];
    
      exports.module.rules = [
        {
          test: /.js$/,
          use: 'happypack/loader?id=jsx'
        },
        {
          test: /.less$/,
          use: 'happypack/loader?id=styles'
        }
      ]
    
     

     

    thread-loader:每次 webpack 解析一个模块,thread- loader 会将它及它的依赖分配给 worker 线程中

    module.exports = {
        module: {
          rules: [
            {
              test: /.js$/,
              include: path.resolve("src"),
              use: [
              {
                loader: "thread-loader"
                options: {
                    workers: 2  // worker的数量,默认是cpu核心数
            }
            }
           }
          ]
        }
      }

     

    3.多进程并行压缩代码

    terser-webpack-plugin 开启parallel参数

    const TerserPlugin = require('terser-webpack-plugin');
    
     module.exports = {
       optimization: {
         minimize: true,
         minimizer: [
           new TerserPlugin({
             parallel: true
           })
         ]
       }
     };

     

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

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

     

    webpack.dll.config.js文件

    const path = require('path');
    
    const webpack = require('webpack');
    
      module.exports = {
        context: process.cwd,
        resolve: {
          extensions: ['.js', '.jsx', '.json', '.styl', '.css'],
          modules: [__dirname, 'node_modules']
        },
        entry: {
          vendor: [
            'react',
            'react-dom',
            'react-router-dom'
          ]
        },
        output: {
          path: path.resolve(__dirname, './dist/lib'),
          filename: '[name].js',
          library: '[name]'
        },
        plugins: [
          new webpack.DllPlugin({
            path: path.resolve(__dirname, '.', '[name]-manifest.json'),
            name: '[name]'
          })
        ]
      };

     

    运行 webpack --config webpack.dll.config.js --mode production 生成vendor-manifest.json文件

     

    webpack.config.js文件

    module.exports = {
       plugins: [
        new webpack.DllReferencePlugin({
             manifest: require('./vendor-manifest.json')
           })
       ]
      }

     

    html: <script type="text/javascript" src="./lib/vendor.js"></script>

     

    5.基础库分离

     

    (1)通过html-webpack-externals-plugin,然后在html里面直接引入组件库的cdn链接

    const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin')
    
      moudles.export = {
    
          plugins: [
              new HtmlWebpackExternalsPlugin({
                  externals: [
                      {
                          module: 'react',
                          entry: '//11.url.cn/now/lib/16.2.0/react.min.js',
                          global: 'React'
                      },
                      {
                          module: 'react-dom',
                          entry: '//11.url.cn/now/lib/16.2.0/react-dom.min.js',
                          global: 'ReactDom'
                      }
                  ]
              })
          ]
      } 

    html:

    <script type="text/javascript" src="https://11.url.cn/now/lib/16.2.0/react.min.js"></script>

    <script type="text/javascript" src="https://11.url.cn/now/lib/16.2.0/react-dom.min.js"></script> 

     

    (2) 通过webpack4SplitChunksPlugins(webpack3使用的是commonChunksPlugin)

    module.exports = {
           plugins: [
               new HtmlWebpackPlugin({
                   template: path.join(__dirname, `./src/pages/search/search.html`),
                   filename: `search.html`,
                   chunks: ['vendors', 'common', 'search'], //注意这里要引入vendors跟common
                   inject: true,
                   minify: {
                       html5: true,
                       collapseWhitespace: true,
                       preserveLineBreaks: false,
                       minifyCSS: true,
                       minifyJS: true,
                       removeComments: false
                   }
               })
           ]
           optimization: {
               splitChunks: {
                   minSize: 0,
                   cacheGroups: {
                       vendors: {
                           test: /(react|react-dom)/,
                           name: 'vendors',
                           chunks: 'all',
                           priority: -10   // 需要设置权重才能都分离出来
                       },
                       common: {
                           name: 'commons',
                           chunks: 'all',
                           minChunks: 2,
                           priority: -20   
                       }
                   }
               }
           }
       }

     

     

    6.利用缓存:第一次构建花费正常的时间,第二次构建将显著加快

     

       babel-loader 开启缓存

    module: {
        rules: [
          {
            test: /.js$/,
            exclude: 'node_modules',
            use: {
              loader: 'babel-loader',
              options: {
                cacheDirectory: true
              }
            }
          }
        ]
      }

     terser-webpack-plugin 开启缓存

    module.exports = {
        optimization: {
          minimize: true,
          minimizer: [
            new TerserPlugin({
              cache: true
            })
          ]
        }
      }

    使用 cache-loader 或者 hard-source-webpack-plugin

    module.exports = {
        module: {
          rules: [
            {
              test: /.js$/,
              use: [
                'cache-loader',
                'babel-loader'
              ],
              include: path.resolve('src')
            }
          ]
        }
      }

     

    7.缩小构建目标(尽可能少的构建模块)

     1babel-loader不解析node-modules

    exclude: "node-modules"

    (2)减少文件搜索范围

    优化 resolve.modules 配置(减少模块搜索层级) 

    优化 resolve.mainFields 配置

    优化 resolve.extensions 配置

    合理使用 alias(模块别名相对于当前上下文导入)

    module: {
        resolve: {
          alias: {
            react: path.resolve(__dirname, './node_modules/react/dist/react.min.js')
          },
          modules: [path.resolve(__dirname, 'node_modules')],
          extensions: ['.js'],
          mainFields: ['main']
        }
      }

     

    体积优化

     

    1.Scope Hoisting 

    将所有模块的代码按照引⽤顺序放在⼀个函数作⽤域里,然后适当的重命名⼀些变量以防⽌变量名冲突

      webpack4  mode production 默认开启

      new webpack.optimize.ModuleConcatenationPlugin()

     

    2.使用Tree shaking擦除无用的javaScriptcss

    概念:1 个模块可能有多个方法,只要其中的某个方法使用到了,则整个文件都会被打到 bundle ⾥去,tree shaking 就是只把用到的方法打⼊ bundle ,没⽤到的方法会在 uglify 阶段被擦除掉。

    使⽤:webpack production mode的情况下默认开启

    要求:必须是 ES6 的语法,CJS 的方式不支持

     

     css:purgecss-webpack-plugin mini-css-extract-plugin 配合使用

     

    3.图片压缩

    配置image-webpack-loader

     loader: "image-webpack-loader"

     

    4.使用动态polyfill-service或者browserlist

       根据浏览器的UA来判断当前浏览器缺失哪些特性,进而进行补强

     

     

     

  • 相关阅读:
    CSS换行和省略号
    html+canvas实现很真实的下雨雨落
    CSS取消鼠标点击事件
    js某时间与当前时间差
    uniapp微信小程序canvas隐藏
    canvas生成圆图和微信小程序canvas圆图
    uniapp微信小程序canvas绘图插入网络图片不显示
    uniapp微信小程序分享(朋友圈分享)
    关于sure 等同根词的演化
    Stress and rhythm in English pronunciation
  • 原文地址:https://www.cnblogs.com/vicky24k/p/12310394.html
Copyright © 2020-2023  润新知