webpack打包速度和体积优化总结

一、webpack速度分析:speed-measure-webpack-plugin

(1)使用 

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

 (2)作用:

  • 分析整个打包总耗时
  • 每个插件和loader的耗时情况

二、webpack体积分析:webpack-bundle-analyzer

(1)使用:构建完成后会在 8888 端口展示大小

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

(2)作用

  • 分析依赖的第三方模块文件大小
  • 分析业务里面的组件代码大小

 三、使用高版本的 webpack 和 Node.js

 (1)使用 webpack4:优化原因:

 四、多进程/多实例构建

 (1)资源并行解析可选方案

 

(2) 使用 HappyPack解析资源

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

 2、使用

 (2)使用 thread-loader 解析资源

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

 

(3) 并行压缩

1、使用 parallel-uglify-plugin 插件

 

 2、uglifyjs-webpack-plugin 开启 parallel参数

 

 3、terser-webpack-plugin 开启 parallel参数

 

 五、分包:设置 Externals

(1)思路:将 react、react-dom 基础包通过 cdn 引入,不打入 bundle 中

(2)方法:使用 html-webpack-externals- plugin

 

六、预编译资源模块 

(1)思路:将 react、react-dom、redux、react-redux 基础包和业务基础包打包成一个文件

(2)方法:使用 DLLPlugin 进行分包,DllReferencePlugin对 manifest.json 引用

 (3)过程

1、新建一个配置文件

2、 在 webpack.config.js 使用 DllReferencePlugin 引用 manifest.json

3、引用效果

 

 七、缓存

(1) 目的:提升二次构建速度

(2) 缓存思路

  • babel-loader 开启缓存 
  • terser-webpack-plugin开启缓存 
  • 使用 cache-loader 或者 hard-source-webpack-plugin

八、 缩小构建目标

(1)目的:尽可能的少构建模块

 九、减少文件搜索范围

  • 优化 resolve.modules 配置(减少模块搜索层级)
  • 优化 resolve.mainFields 配置(包入口文件)
  • 优化 resolve.extensions 配置(扩展名)
  • 合理使用 alias(别名路径搜索)

 

 十、图片压缩

(1)使用:配置 image-webpack-loader

(2)要求:基于 Node 库的 imagemin 或者 tinypng API

 

(3) Imagemin的优点分析

  • 有很多定制选项
  • 可以引入更多第三方优化插件,例如pngquant
  • 可以处理多种图片格式

 (4)Imagemin的压缩原理

 十一、tree shaking(摇树优化)

(1)概念

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

(2)使用

  • webpack 默认支持,在 .babelrc 里设置 modules: false 即可
  • production mode的情况下默认开启

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

十二、 删除掉无用的 CSS 

  • PurifyCSS: 遍历代码,识别已经用到的 CSS class
  • uncss: HTML 需要通过 jsdom 加载,所有的样式通过PostCSS解析,通过 document.querySelector 来识别在 html 文件里面不存在的选择器

 (1)使用 purgecss-webpack-pluginmini-css-extract-plugin 配合使用

 

 十三、动态 Polyfill

(1)原因:babel-polyfill 打包后体积:88.49k,占比 29.6%

(2) Polyfill Service原理

 识别 User Agent,下发不同的 Polyfill

 

 (3) 使用动态 Polyfill service

 十四、总结

(1)打包速度优化

1、使用高版本的webpack和Node.js

2、多进程打包:happyPack或thread-loader

3、多进程并行压缩:parallel-uglify-plugin、uglifyjs-webpack-plugin 开启 parallel 参数、terser-webpack-plugin 开启 parallel 参数

4、预编译资源模块:DLLPlugin

5、缓存(babel-loader、terser-webpack-plugin、cache-loader)

6、exclude、include缩小构建目标,noParse忽略、IgnorePlugin

7、resolve配置减少文件搜索范围(alias、modules、extensions、mainFields)

(2)打包体积优化

1、Tree-shaking擦除无用代码

2、Scope Hoisting优化代码

3、图片压缩(image-webpack-loader)

4、公共资源提取(CommonsChunkPlugin)

5、动态Polyfill

6、分包设置Externals,使用 html-webpack-externals- plugin,将 react、react-dom 基础包通过 cdn 引入,不打入 bundle 中

7、删除无用CSS代码(purgecss-webpack-plugin)

8、JS、CSS压缩(UglifyJsPlugin(3)、terser-webpack-plugin(4)、optimize-css-assets-webpack-plugin)


版权声明:本文为qq_40542728原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。