如何对Webpack进行优化

Webpack 的优化瓶颈,主要是 2 个方面:

  • Webpack 的构建过程太花时间
  • Webpack 打包的结果体积太大

1.1 针对 Webpack 本身构建优化

1.1.1 优化 resolve.modules 配置

resolve.modules 用于配置 Webpack 去哪些目录下寻找第三方模块,默认是 ['node_modules'],但是,它会先去当前目录的 ./node_modules 查找,没有的话再去 ../node_modules,最后到根目录。

所以可以直接指定项目根目录,就不需要一层一层查找。

resolve: {
  modules: [path.resolve(__dirname, 'node_modules')],
}

1.1.2 优化 resolve.extensions 配置

在导入没带文件后缀的路径时,Webpack 会自动带上后缀去尝试询问文件是否存在,而 resolve.extensions 用于配置尝试后缀列表;默认为 extensions:['js', 'json']

当遇到 require('./data') 时 Webpack 会先尝试寻找 data.js,没有再去找 data.json;如果列表越长,或者正确的后缀越往后,尝试的次数就会越多。

所以在配置时为提升构建优化需遵守:

  1. 频率出现高的文件后缀优先放在前面。
  2. 列表尽可能的少,例如只有 3 个:jsjsxjson
  3. 书写导入语句时,尽量写上后缀名。

1.2 通过 Loader 和 Plugin 优化

1.2.1 babel-loader

以 babel-loader 为例,可以通过 include 和 exclude 帮助我们避免 node_modules 这类庞大文件夹。

1.2.2 tree shaking

通过 ES6 的 import/export 来检查未引用代码,以及 sideEffects 来标记无副作用代码,最后用 UglifyJSPlugin 来做 tree shaking,从而删除冗余代码。

1.2.3 可视化分析

  • speed-measure-webpack-plugin:测量出在构建过程中,每一个 Loader 和 Plugin 的执行时长。
  • webpack-bundle-analyzer:通过矩阵树图的方式将包内各个模块的大小和依赖关系呈现出来。
  • webpack-chart
  • webpack-analyse

1.2.4 缓存

  • cache-loader

参考链接:cache-loader

在 babel-loader 开启 cache 后,将 loader 的编译结果写进硬盘缓存,再次构建如果文件没有发生变化则会直接拉取缓存。

  • uglifyjs-webpack-plugin

也可以解决缓存问题。

1.2.5 多进程

Happypack 可以将任务分解成多个子进程去并发执行,大大提升打包效率。

1.2.6 抽离

通过 DllPlugin 或者 Externals 进行静态依赖包的分离。

由于 CommonsChunkPlugin 每次构建会重新构建一次 vendor,所以出于效率考虑,使用 DllPlugin 将第三方库单独打包到一个文件中,只有依赖自身发生版本变化时才会重新打包。

1.2.7 多进程代码压缩

因为自带的 UglifyJsPlugin 压缩插件是单线程运行的,而 ParallelUglifyPlugin 可以并行执行。

所以通过 ParallelUglifyPlugin 代替自带的 UglifyJsPlugin 插件。

1.2.8 拆包

在 Webpack 中,到底什么是代码分离?代码分离允许你把代码拆分到多个文件中。如果使用得当,你的应用性能会提高很多。因为浏览器能缓存你的代码。

每当你做出一次修改,包含修改的文件需要被所有访问你网站的人重新下载。但你并不会经常修改应用的依赖库。

如果你能把那些依赖库拆分到完全分离的文件中,即使业务逻辑发生了更改,访问者也不需要再次下载依赖库,直接使用之前的缓存就可以了。

由于有了 SplitChunksPlugin,你可以把应用中的特定部分移至不同文件。如果一个模块在不止一个 chunk 中被使用,那么利用代码分离,该模块就可以在它们之间很好地被共享。

1.2.9 打包资源压缩

  • JS 压缩:UglifyJSPlugin
  • HTML 压缩:HtmlWebpackPlugin
  • 提取公共资源:splitChunks.cacheGroups
  • CSS 压缩:MiniCssExtractPlugin
  • Gzip 压缩:不包括图片

1.2.10 按需加载

通过 Code-Splitting 来做 React 的按需加载.

Code_Splitting 核心是 require-ensure

1.3 优化体验

  • progress-bar-webpack-plugin:在终端底部,将会有一个构建的进度条,可以让你清晰的看见构建的执行进度。
  • webpack-build-notifier:在构建完成时,能够像微信、Lark 这样的 APP 弹出消息的方式,提示构建已经完成。
  • webpack-dashboard:对 Webpack 原始的构建输出不满意的话,也可以使用这样一款 Plugin 来优化你的输出界面。

 

评论

还没有评论...留下你的评论!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Sidebar