webpack 打包优化 - splitChunks

打包时会遇到的问题:

  1. 打包文件过大,首屏加载时间过长,js阻塞页面渲染导致白屏
  2. 改动业务代码后,对于第三方库也会一并重新打包到一个出口文件,浏览器无法利用缓存来减少请求和加载的时间

针对以上两个问题,利用splitChunks可以将各个模块进行分割,并提取出相同部分代码,从而缓解一个js过大、不能缓存第三方库的问题。

webpack 从 4.x 开始支持了零配置的特性,同时对块打包也做了优化,CommonsChunkPlugin已经被移除了,现在是使用optimization.splitChunks代替。(webpack5 splitChunks 配置和 webpack4 大体上一样)

概念区分 - module、bundle、chunk都是什么?

在说SplitChunks前,先来了解几个概念,module、bundle、chunk都是什么?

module:模块,在webpack中任何文件都可以作为一个模块,借用官网的图片,左侧的这些类型文件,都可以认为是一个模块,只是需要配置不同的loader,将文件转换成webpack可以支持打包的文件。

chunk:编译完成准备输出时,webpack 将module 按特定规则组成的一个个 chunk

bundle:webpack 处理好chunk文件后,生成运行在浏览器中的代码

SplitChunks 插件是什么呢

简单的来说就是 Webpack 中一个提取或分离代码的插件,主要作用是提取公共代码,防止代码被重复打包,拆分过大的js文件,合并零散的js文件。

提到前端优化,提取公共代码是必不可少的手段。
在 Webpack 出现前,提取公共代码是人为去处理,而 SplitChunks 插件的作用就是通过配置让 Webpack 去帮你提取公共代码。SplitChunksPlugin 默认配置适用大部分场景。

打包默认情况下只会影响按需加载模块,因为对初始块也进行优化打包会影响 HTML 中的 script 标签数,增加请求数。

默认情况(webpack 的默认配置)下 webpack 会根据下述条件自动进行代码块分割:

  • 共享模块(至少被引用 2次)或者 node_modules 模块
  • 新代码块大于 20kb(min+gziped之前的体积)
  • 按需加载块时的最大并行请求数将低于或等于 30
  • 初始页面加载时的最大并行请求数将低于或等于 30

SplitChunks插件配置选项

  • 同步加载的模块:通过 import xxx 或 require(‘xxx’) 加载的模块。
  • 异步加载的模块:通过 import(‘xxx’) 或 require([‘xxx’],() =>{}) 加载的模块。
  • chunks: 表示哪些代码需要优化,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),chunks 选项,决定要提取哪些模块
    • 默认是 async :只提取异步加载的模块出来打包到一个文件中。
    • initial 模块下只优化初始模块,也就是说 webpack 只会对初始模块做打包优化。如果 xxx 在项目中异步加载了,也同步加载了,那么 xxx 这个模块会被提取两次,分别打包到不同的文件中。
    • all 模块下同时对初始模块和异步模块做打包优化,不管异步加载还是同步加载的模块都提取出来,打包到一个文件中。
  • minSize: 规定被提取的模块在压缩前的大小最小值,单位为字节。表示在压缩前的最小模块大小,默认为 20000
  • minChunks: 表示被引用次数,默认为 1
  • maxAsyncRequests: 按需加载时候最大的并行请求数,默认为 30
  • maxInitialRequests: 一个入口最大的并行请求数,默认为 30
  • enforceSizeThreshold:强制执行拆分的体积阈值
  • cacheGroups: 缓存组。缓存组的属性除上面所有属性外,还有 test, priority, reuseExistingChunk
    • test: 用于控制哪些模块被这个缓存组匹配到
    • priority: 缓存组打包的先后优先级
    • reuseExistingChunk: 如果当前代码块包含的模块已经有了,就不在产生一个新的代码块

实际使用情景:

1. 设置 chunks: initial || all 都可以提取出第三方库。但是它是把所有第三库提取出来,所以我们在只提取 react 和 react-dom 的情况下,需要自定义一个 cacheGroup。

// webpack.config.js
optimization: {splitChunks: {chunks: 'all',cacheGroups: {react: {name: 'react',test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,}}}
}

安装  webpack-bundle-analyzer, 可以查看打包体积情况,在package.json 中,npm run build 的地方写一个 --report 就会在打包文件中生成一个 report.html, 打开可以看到打包体积情况。  "build": "vue-cli-service build --report"

2. 比如发现chunk-vendors.js的大小有点大了,有1.91MB,还是项目初始化时需要加载的 js 文件,大小过大会导致首屏加载时间过长。

要优化一下,两种方法:可以用SplitChunks优化。

例如要把element从chunk-vendors.js提取出来,就在cacheGroups 进行对应配置:

chainWebpack(config) {config.when(process.env.NODE_ENV != 'development',config => {config.optimization.splitChunks({chunks: 'all',cacheGroups: {// 第三方组件libs: {// 指定chunks名称name: 'chunk-libs',//符合组的要求就给构建venderstest: /[\\/]node_modules[\\/]/,//priority:优先级:数字越大优先级越高,因为默认值为0,所以自定义的一般是负数形式,决定cacheGroups中相同条件下每个组执行的优先顺序。priority: 10,// 仅限于最初依赖的第三方chunks: 'all'},elementUI: {// 将elementUI拆分为单个包name: 'chunk-elementUI',// 重量需要大于libs和app,否则将打包到libs或app中priority: 20,// 为了适应cnpmtest: /[\\/]node_modules[\\/]_?element-ui(.*)/},//公共组件//   commons: {//       name: 'chunk-commons',//       // can customize your rules//       test: resolve('src/components'),//       minChunks: 3,//       priority: 30,//       //这个的作用是当前的chunk如果包含了从main里面分离出来的模块,则重用这个模块,这样的问题是会影响chunk的名称。//       reuseExistingChunk: true,//       //最大初始化加载次数,一个入口文件可以并行加载的最大文件数量,默认3//       maxInitialRequests: 3,//       //表示在分离前的最小模块大小,默认为0,最小为30000//       minSize: 0//   },}})})}

总结:

webpack5 默认情况下只对异步模块做打包优化,额外的打包必须满足 4 个条件(webpack 的默认配置,可修改)。根据需求可调整为只对初始模块做打包优化,或者初始和异步模块一起优化。同时可配置自己的打包规则。

简而言之:chunks 控制打包作用范围,其他控制打包规则。

webpack5 的 splitChunks 功能是比较强大的,不过推荐还是使用默认模式,或者提取一下第三方库。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/313981.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

paddlepaddle-gpu安装

背景 之前安装paddlepaddle-gpu遇到各种问题,安装不成功,之前使用了wsldocker的方式,可查看我之前博客:记录paddlepaddle-gpu安装,这要会导致我整个开发流程比较割裂 cuda版本 强烈推荐cuda11.8,paddlep…

【讯为Linux驱动笔记1】申请一个字符设备

Linux下每个设备都需要有一个专属设备号:主设备号 次设备号 【申请字符设备】 主设备号:一类驱动:如:USB驱动 次设备号:这类驱动下的某个设备 如:键盘鼠标 设备号是32位的dev_t类型的,高12位主…

【黑马头条】-day12项目部署和发布-jenkins

文章目录 1 持续集成2 软件开发模式2.1 瀑布模式2.2 敏捷开发2.2.1 迭代开发2.2.2 增量开发 3 Jenkins3.1 Jenkins安装3.1.1 导入镜像3.1.2 配置3.1.3 初始化设置 3.2 插件安装3.3 服务器环境准备3.3.1 Docker安装配置3.3.2 Git安装配置3.3.3 Maven安装配置 3.4 Jenkins工具配置…

亚信安全入选中国数据安全市场图谱

近日,全球领先的IT市场研究和咨询公司IDC发布了《IDC Market Glance:中国数据安全市场图谱,2024》报告(以下简称“报告”),报告展示了中国数据安全市场的构成和格局,遴选出不同细分市场领域的主…

管理 Python 项目的艺术:在 PyCharm 中使用虚拟环境(以BPnP为例)

在 PyCharm 中使用虚拟环境对于 Python 项目开发具有多方面的重要作用,这些作用体现在提升项目管理的效率、保障代码的可运行性以及维护项目的长期稳定性等方面。以下是使用虚拟环境的几个关键好处: 1. 依赖管理和隔离 虚拟环境允许每个项目拥有…

工作记录:vue-grid-layout 修改 margin 导致 item 高度剧烈变化

问题 用 vue-gird-layout 时发现,当改变 margin 值时,item 的尺寸也会跟着变化。 如下图:row height 和每个 item 的 h 都保持不变。修改 margin-y,item 的实际高度也跟着变了: 原因 研究了一番,发现原…

flutter release 报错 Error: SocketException: Failed host lookup:

flutter 的 debug 模式没有任何问题 ,打了release 包后一直报下面的错,查了一下是 因为没有网络权限 Error: SocketException: Failed host lookup: yomi-test-aws-sg.yomigame.games (OS Error: No address associated with hostname, errno 7) 按照下…

组合模式【结构型模式C++】

1.概述 组合模式又叫部分整体模式属于结构型模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。 2.结构 组件(Component):定义了组合中所有对象的通用接口&#xff0c…

OpenHarmony鸿蒙南向开发案例:【智能窗户通风设备】

样例简介 本文档介绍了安全厨房案例中的相关智能窗户通风设备,本安全厨房案例利用轻量级软总线能力,将两块欧智通V200Z-R/BES2600开发板模拟的智能窗户通风设备和燃气告警设备组合成。当燃气数值告警时,无需其它操作,直接通知软总…

程序员学CFA——数量分析方法(四)

数量分析方法(四) 常见概率分布基本概念离散型随机变量与连续型随机变量离散型随机变量连续型随机变量 分布函数概率密度函数(PDF)累积分布函数(CDF) 离散分布离散均匀分布伯努利分布二项分布定义股价二叉树…

OpenStack云计算(十一)——OpenStack网络管理,验证OpenStack网络资源模型,验证来巩固和加深对OpenStack网络资源模型的理解

项目实训一 【实训题目】 验证OpenStack网络资源模型 【实训目的】 通过验证来巩固和加深对OpenStack网络资源模型的理解。 【实训准备】 (1)复习Neutron网络资源模型。 (2)重点理解网络、子网、端口和路由器的概念。 【实…

GPB | RegVar:基于深度神经网络的非编码区突变功能预测新方法

Genomics, Proteomics & Bioinformatics (GPB)发表了由军事医学研究院辐射医学研究所张成岗研究员、周钢桥研究员和卢一鸣副研究员团队完成的题为“RegVar: Tissue-specific Prioritization of Noncoding Regulatory Variants”的方法文章。我们的“…

【Redis 开发】一人一单,超卖问题(悲观锁,乐观锁,分布式锁)

锁 悲观锁乐观锁第一种:版本号法第二种:CAS法实现乐观锁 悲观锁与乐观锁的比较 一人一单分布式锁Redis实现分布式锁 悲观锁 认为线程问题一定会发生,因此在操作数据库之前先获取锁,确保线程串行执行,例如Synchronized…

【Leetcode】vector刷题

🔥个人主页:Quitecoder 🔥专栏:Leetcode刷题 目录 1.只出现一次的数字2.杨辉三角3.删除有序数组中的重复项4.只出现一次的数字II5.只出现一次的数字III6.电话号码的字母组合 1.只出现一次的数字 题目链接:136.只出现一…

HCIP-Datacom-ARST必选题库_01_ACL【7道题】

一、单选 1.下面是一台路由器的部分配置,关于该配置描述正确的是: 源地址为1.1.1.1的数据包匹配第一条ACL语句rule 0,匹配规则为允许 源地址为1.1.1.3的数据包匹配第三条ACL语句rule 2,匹配规则为拒绝 源地址为1.1.1.4的数据包匹配第四条ACL语句rule 3,匹配规则为允…

Scala 05 —— 函数式编程底层逻辑

Scala 05 —— 函数式编程底层逻辑 该文章来自2023/1/14的清华大学交叉信息学院助理教授——袁洋演讲。 文章目录 Scala 05 —— 函数式编程底层逻辑函数式编程假如...副作用是必须的?函数的定义函数是数据的函数,不是数字的函数如何把业务逻辑做成纯函…

python爬虫学习------scrapy第二部分(第三十天)

🎈🎈作者主页: 喔的嘛呀🎈🎈 🎈🎈所属专栏:python爬虫学习🎈🎈 ✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天…

底层逻辑(1) 是非对错

底层逻辑(1) 是非对错 关于本书 这本书的副标题叫做:看清这个世界的底牌。让我想起电影《教父》中的一句名言:花半秒钟就看透事物本质的人,和花一辈子都看不清事物本质的人,注定是截然不同的命运。 如果你看过梅多丝的《系统之美…

数据挖掘实验(Apriori,fpgrowth)

Apriori:这里做了个小优化,比如abcde和adcef自连接出的新项集abcdef,可以用abcde的位置和f的位置取交集,这样第n项集的计算可以用n-1项集的信息和数字本身的位置信息计算出来,只需要保存第n-1项集的位置信息就可以提速…

2024年巴黎奥运会临近,中国义乌又爆弹了?网友:这就是硬核实力

奥运订单热潮涌动,中国制造不可或缺 随着巴黎奥运会脚步的日益临近,中国义乌再次聚焦全球视野。 近日,国货探访浙江义乌国际商贸城,发现众多蕴含法国元素的商品被置于显眼位置,吸引众多采购商纷至沓来,争…