Webpack性能优化 SplitChunksPlugin的使用详解
使用前景
在vue、react等使用webpack为项目打包工具的前端项目,在开发过程中,随着项目功能的逐渐增加,项目整体体积的不断增加,打包的时长和打包后部署的项目体积也在不停的增长,这样可能会导致一下两个问题:
- 使用自动化部署工具Jenkins部署时,Jenkins因内存不足而崩溃
- 打包产物过大,用户的首屏加载缓慢,网页响应用户操作时延较长,令用户感觉卡顿,整体体验不佳
解决方式
代码分片与公共模块提取
优点:
- 开发过程中减少重复模块打包,可以提升开发速度
- 减少整体资源体积
- 合理分片后的代码可以更有效地利用客户端缓存
使用插件
- 在webpack3中使用CommonChunksPlugin (不在这里展开说明)
- 在webpack4及之后的版本使用SplitChunksPlugin
CommonChunksPlugin
CommonsChunkPlugin是一个可选功能,它创建一个单独的文件(称为块),由多个入口点之间共享的公共模块组成。
通过将通用模块从bundle中分离出来,生成的块文件可以在最初加载一次,并存储在缓存中供以后使用。这可以优化页面速度,因为浏览器可以快速地从缓存中提供共享代码,而不是在访问新页面时强制加载更大的包。它具有以下优点
SplitChunksPlugin
最初,chunks(以及内部导入的模块)是通过内部 webpack 图谱中的父子关系关联的。CommonsChunkPlugin 曾被用来避免他们之间的重复依赖,但是不可能再做进一步的优化。
从 webpack v4 开始,移除了 CommonsChunkPlugin,取而代之的是 optimization.splitChunks。
SplitChunksPlugin 的配置
部分配置项说明
splitChunks.chunks
这表明将选择哪些 chunk 进行优化。当提供一个字符串,有效值为 all,async 和 initial。设置为 all 可能特别强大,因为这意味着 chunk 可以在异步和非异步 chunk 之间共享。
splitChunks.cacheGroups
缓存组可以继承和/或覆盖来自 splitChunks.* 的任何选项。但是 test、priority 和 reuseExistingChunk 只能在缓存组级别上进行配置。将它们设置为 false以禁用任何默认缓存组
splitChunks.cacheGroups.{cacheGroup}.reuseExistingChunk
默认值为 true
如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块。这可能会影响 chunk 的结果文件名。
splitChunks.cacheGroups.{cacheGroup}.priority
一个模块可以属于多个缓存组。优化将优先考虑具有更高 priority(优先级)的缓存组。默认组的优先级为-20,以允许自定义组获得更高的优先级(自定义组的默认值为 0)。
注意:优先级值会影响html中打包后js的引入顺序
默认配置
optimization: { splitChunks: { chunks: 'async', minSize: 20000, minRemainingSize: 0, minChunks: 1, maxAsyncRequests: 30, maxInitialRequests: 30, enforceSizeThreshold: 50000, cacheGroups: { defaultVendors: { test: /[\\/]node_modules[\\/]/, priority: -10, reuseExistingChunk: true, }, default: { minChunks: 2, priority: -20, reuseExistingChunk: true, }, }, }, },
配置例子
optimization:{ splitChunks:{ chunks: "all", minSize:20000,// 允许新拆出 chunk 的最小体积,也是异步 chunk 公共模块的强制拆分体积 maxAsyncRequests:6,// 每个异步加载模块最多能被拆分的数量 maxInitialRequests: 6,// 每个入口和它的同步依赖最多能被拆分的数量 enforceSizeThreshold:50000,// 强制执行拆分的体积阈值并忽略其他限制 cacheGroups:{ libs:{ // 第三方库 name: "chunk-libs", test: /[\V/]node_modules[\\/]/, priority: 10, chunks:"initial”// 只打包初始时依赖的第三方 }, ckeditor5_document:{ // 第三方库 name:"chunk-ckeditor5-document", test:/[\V/]assets[\V/]common[\V/]js[\V/]ckeditor5[\\/]ckeditor5-build-decoupled-document[\//]/, priority: 20 }, ckeditor5_vue2:{ // 第三方库 name:"chunk-ckeditor5-vue2", test:/[\V/]assets[\V/]common[\V/]js[\V/]ckeditor5[\\/]ckeditor5-vue2[\\/]/, priority:20 }, elementUI:{ // elementuI 单独拆包 name:"chunk-elementUI", test:/[\V/]node_modules[\V]element-ui[\/]/, priority: 20 // 权重要大于 libs }, echarts:{ // echarts 单独拆包 name:"chunk-echarts", test: /[\\/]node_modules[\V/]echarts[\\/]/, priority: 20 // 权重要大于 libs }, src:{ // echarts 单独拆包 name:"chunk-src", test: /[\V/]src[\\/]/, chunks:'all', priority: 10 // 权重要大于 libs }, commons:{ // 公共模块包 name: `chunk-commons`, minChunks:2, priority: 0, reuseExistingChunk:true // } } ] }
配置前后打包对比
使用打包分析插件
webpack-bundle-analyzer:一个 plugin 和 CLI 工具,它将 bundle 内容展示为一个便捷的、交互式、可缩放的树状图形式。
安装
# NPM npm install --save-dev webpack-bundle-analyzer # Yarn yarn add -D webpack-bundle-analyzer
用法(在webpack配置文件中)
const { BundleAnalyzerPlugin }= require('webpack-bundle-analyzer'); ... plugins: [ new BundleAnalyzerPlugin() ]
打包分析
使用配置前
使用配置后
使用前 | 使用后 | |
---|---|---|
包体积 | 24.69MB | 8.23MB |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)