浅析 SplitChunksPlugin 及代码分割的意义

news2025/7/19 0:10:07

本文作者为 360 奇舞团前端开发工程师

起因

有同事分享webpack的代码分割,其中提到了SplitChunksPlugin,对于文档上的描述大家有着不一样的理解,所以打算探究一下。

Q:什么是 SplitChunksPluginSplitChunksPlugin 是用来干嘛的?

A: 最初,chunks(以及内部导入的模块)是通过内部webpack 图谱中的父子关系关联的。CommonsChunkPlugin曾被用来避免他们之间的重复依赖,但是不可能再做进一步的优化。从webpack v4 开始,移除了CommonsChunkPlugin,取而代之的是 optimization.splitChunksSplitChunksPlugin可以去重和分离 chunk

webpack的中文文档,对SplitChunksPlugin的描述是这样子的:

357b61868859ccb76a1d38a5d35560fb.png

针对以上的第二点描述新的 chunk 体积大于 20kb(在进行 min+gz 之前的体积),有同事是这么理解的:chunk 大于 20kb 时,webpack会对当前的chunk进行拆包,一般情况下,100kb的包会拆成 5 个包 即 5 * 20kb = 100kb.  如果有并发请求的限制,webpack会自动把某些包合并,如并发请求数是 2 ,那么这个100kb的包将会被拆成 2 个,每个包的大小为50kb,即 2 * 50kb = 100kb

而我对此表示有不同的看法:既然这个插件是用来对代码进行分割的,那么没有必要再对代码进行合并,这样子会让这个插件变得不纯粹,而且会增加插件逻辑的复杂度,所以这句话的意思应该是分割出来的新chunk得大于 20kb。

由于大家都不是三言两语就能被说服的,所以打算去查查资料,动动手验证一下到底是怎么一回事。

文档资料

一、英文文档

首先为了避免中华语言博大精深,导致个人理解有偏差,我先去查看了一下英文文档,英文文档上是这么描述的:

bb88b47630b2bd618c73d3a10ae245bb.png

关键词 new chunk:新的chunk,只有分离出来的才算是新的chunk吧,那么这句话的意思应该就是新的chunk将会大于20kb

二、社区文章

其次为了再次避免个人英文理解有偏差,到网上去翻阅了一些社区文章:

fa883e124a2a55f004bca63430c9caff.png

作者:前端论道 链接:https://juejin.cn/post/6844904103848443912 来源:稀土掘金

从上图中可以看到,第三方包vue已经超过了默认的20kb,直接被分割成一个单独的2.js的包,并不是按照20kb平均分成多个包。

动手实践

// index.js
import "./a";
console.log("this is index");
// a.js
import "vue";
import "react";
import "jquery";
import "lodash";
console.log("this is a");
// webpack.config.js
const path = require('path');

module.exports = {
    mode: "production",
    entry: './src/index.js',
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist'),
    },
    optimization: {
        splitChunks: {
            chunks: 'all',
        },
    },
};

编译结果:1bd3f95bd2144bafae379fdbbd7e2f33.png

从编译的结果中可以看到,除了main.js,仅仅多出了一个205kb46.jsa0211b0148332c293b4d7a8b0f9586f0.png从上图可以看出,vuejquerylodash等一起都被打包到 46.js 中,并没有以20kb为基础平均分割成很多个chunk

结论

新的 chunk 体积大于 20kb(在进行 min+gz 之前的体积),指的是引入的依赖中,在进行min+gz之前的体积大于20kb,这个依赖将会被分割出来成为一个新的chunk

新的疑问

到这里还没有结束,因为我还有几个疑问:

  1. webpack为什么要进行代码分割?

  2. 浏览器的并发请求一般不是4~6个吗?为什么文章里提到的按需请求和初始请求都是小于或者等于30?

webpack为什么要进行代码分割?

  • 前端代码体积变大,调试和上线都需要很长的编译时间,开发时修改一行代码也要重新打包整个脚本。

  • 用户需要花额外的时间和带宽下载更大体积的脚本文件。

一、按需加载 首次加载只加载必要的内容,提升用户的首次加载的速度。其他的模块可以根据用户的交互进行按需加载,即用户跳转新路由或者点击的页面的时候再进行加载。

二、有效利用缓存 通过webpack在打包是对代码进行分割,可以有效的利用缓存:打包编译的时候,只需要编译需要更新的部分;用户访问的时候只需要下载被修改的文件即可。

场景:你有一个体积巨大的文件,并且只改了一行代码,用户仍然需要重新下载整个文件。但是如果你把它分为了两个文件,那么用户只需要下载那个被修改的文件,而浏览器则可以从缓存中加载另一个文件。

三、预获取/预加载模块

  • prefetch(预获取):将来某些导航下可能需要的资源:这会生成 <link rel="prefetch" href="login-modal-chunk.js"> 并追加到页面头部,指示着浏览器在闲置时间预取 login-modal-chunk.js 文件。

  • preload(预加载):当前导航下可能需要资源 --- preload chunk 会在父 chunk加载时,以并行方式开始加载。prefetch chunk 会在父 chunk 加载结束后开始加载。--- preload chunk 具有中等优先级,并立即下载。prefetch chunk 在浏览器闲置时下载。--- preload chunk 会在父 chunk 中立即请求,用于当下时刻。prefetch chunk 会用于未来的某个时刻。--- 浏览器支持程度不同。

浏览器的并发请求一般不是4~6个吗?为什么文章里提到的按需请求和初始请求都是小于或者等于30?

随着http2.0的普及,浏览器的并发请求的限制得到了很好的解决。通过http2.0的多路复用,理论上可以通过一个TCP请求发送无数个请求。然后翻了下webpack代码仓库源码,发现了以下注释:

0f05d2e2e042b6b867fe8f4209d373ad.png

http2.0支持情况:

092a10edabbcb4630349fa532c8fea49.png

所以在webpack的代码分割逻辑里,按需请求和初始请求都超过了之前浏览器对http1.0单个域名请求的限制。

参考文档:
webpack中文文档:https://webpack.docschina.org/plugins/split-chunks-plugin/#split-chunks-example-1
webpack英文文档:https://webpack.js.org/plugins/split-chunks-plugin/#root
如何使用 splitChunks 精细控制代码分割:https://juejin.cn/post/6844904103848443912

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

bd29f10a260c2adf7e407580471c4cc0.png

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python所有方向的入门和进阶路线,20年老师傅告诉你方法

干了20多年程序员&#xff0c;对于Python研究一直没停过&#xff0c;这几天把我自己对Python的认知和经验&#xff0c;再结合很多招聘网站上的技术要求&#xff0c;整理出了Python所有方向的学习路线图&#xff0c;基本上各个方向应该学什么&#xff0c;都在上面了&#xff0c;…

macOS 13.3 Beta 3 (22E5236f)发布

系统介绍3 月 8 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 13.3 开发者预览版 Beta 3 更新&#xff08;内部版本号&#xff1a;22E5236f&#xff09;&#xff0c;本次更新距离上次发布隔了 7 天。macOS Ventura 带来了台前调度、连续互通相机、FaceTime 通话接力…

文件预览kkFileView安装及使用

1 前言网页端一般会遇到各种文件&#xff0c;比如&#xff1a;txt、doc、docx、pdf、xml、xls、xlsx、ppt、pptx、zip、png、jpg等等。有时候我们不想要把文件下载下来&#xff0c;而是想在线打开文件预览 &#xff0c;这个时候如果每一种格式都需要我们去写代码造轮子去实现预…

k8s pod调度总结

在Kubernetes平台上&#xff0c;我们很少会直接创建一个Pod&#xff0c;在大多数情况下会通过控制器完成对一组Pod副本的创建、调度 及全生命周期的自动控制任务&#xff0c;如&#xff1a;RC、Deployment、DaemonSet、Job 等。本文主要举例常见的Pod调度。1全自动调度功能&…

第二章:基础语法

第二章&#xff1a;基础语法 2.1&#xff1a;关键字和保留字 关键字 定义&#xff1a;被Java语言赋予了特殊含义&#xff0c;用做专门用途的字符串(单词) 特点&#xff1a;关键字中所有字母都为小写 分类&#xff1a; 用于定义数据类型的关键字 class、interface、enum、byt…

算法设计与分析——递归与分治策略——全排列Perm函数

删除线格式 [toc] 问题描述 现给出m个不同的数字&#xff0c;在n个位置上&#xff0c;对齐进行全排列。使用编程实现数学中全排列输出最终计算结果并将所有的排列打印出来。 思路分析 常规的递归方式进行解决即可&#xff0c;递归的终点是根据题目要求进行实现。共有两个参…

第一次运行vue遇到的问题

1.vue无法识别https://blog.csdn.net/weixin_61634408/article/details/1265897982.yarn serve问题https://blog.csdn.net/fangxuan1509/article/details/104711690/3.关闭控制台报错检查&#xff08;每次vue-rounter必须用&#xff09;vue.config,js,的module.exports 中添加l…

【Linux】sudo指令

在本期博客正式开始之前&#xff0c;我们先来解决一个历史遗留问题&#xff1a;sodu指令怎么用不了&#xff1f;sudo指令&#x1f4cc;sudo是linux下常用的允许普通用户使用超级用户权限的工具&#xff0c;允许系统管理员让普通用户执行一些或者全部的root命令&#x1f4cb;但是…

【预告】ORACLE Unifier v22.12 虚拟机发布

引言 离ORACLE Primavera Unifier 最新系统 v22.12已过去了3个多月&#xff0c;应盆友需要&#xff0c;也为方便大家体验&#xff0c;我近日将构建最新的Unifier的虚拟环境&#xff0c;届时将分享给大家&#xff0c;最终可通过VMWare vsphere (esxi) / workstation 或Oracle …

【Spring6】| Bean的四种获取方式(实例化)

目录 一&#xff1a;Bean的实例化方式 1. 通过构造方法实例化 2. 通过简单工厂模式实例化 3. 通过factory-bean实例化 4. 通过FactoryBean接口实例化 5. BeanFactory和FactoryBean的区别&#xff08;面试题&#xff09; 6. 使用FactoryBean注入自定义Date 一&#xff1a…

Radiant:AR/VR显示系统测试比2D屏难在哪?

我们知道&#xff0c;光学一直是AR/VR的核心技术&#xff0c;为了实现理想的光学显示效果&#xff0c;AR/VR厂商和科研人员不断在解决各种各样的问题。除了光学方案外&#xff0c;光学器件的质量对于AR/VR显示效果也很重要。在DSCC举办的一场AR/VR显示论坛上&#xff0c;光学检…

HashMap底层的实现原理(JDK8)

目录一、知识点回顾二、HashMap 的 put() 和 get() 的实现2.1 map.put(k, v) 实现原理2.2 map.get(k) 实现原理三、HashMap 的常见面试题3.1 为何随机增删、查询效率都很高&#xff1f;3.2 为什么放在 HashMap 集合 key 部分的元素需要重写 equals 方法?3.3 HashMap 的 key 为…

HTML DOM 元素

创建新的 HTML 元素在文档对象模型 (DOM) 中&#xff0c;每个节点都是一个对象。DOM 节点有三个重要的属性&#xff0c;分别是&#xff1a;nodeName : 节点的名称nodeValue &#xff1a;节点的值nodeType &#xff1a;节点的类型创建新的 HTML 元素如需向 HTML DOM 添加新元素&…

一款OutLook信息收集工具

OutLook 这是一款burp插件&#xff0c;用于Outlook用户信息收集&#xff0c;在已登录Outlook账号后&#xff0c;可以使用该 插件自动爬取所有联系人的信息 安装 在burp扩展面板加载jar即可 功能介绍 All Users 加载插件后&#xff0c;进入Outlook联系人面板&#xff0c;…

unity开发知识点小结03

物理关节 铰链关节 按照固定的轴进行旋转 弹簧关节 两物体之间加装弹簧 固定关节 两个物体相关联 射线检测 通过射线检测&#xff0c;我们可以实现用鼠标来移动物体&#xff0c;当我们用鼠标点击场景中的某一位置&#xff0c;摄像机就发出一条射线&#xff0c;并且通过…

zookeeper从安装到入门

文章目录什么是zookeeperzookeeper的安装启动zookeeper并检查是否安装完成zookeeper的一些操作指令zookeeper的JavaAPI建立连接创建节点查询节点修改节点删除节点事件监听分布式锁集群leader选举规则集群角色什么是zookeeper ZooKeeper是一个分布式的&#xff0c;开放源码的分…

Fastjson 1.2.24 命令执行漏洞复现-JNDI简单实现反弹shell

文章目录前言一、环境搭建二、漏洞复现准备三、漏洞复现四、不成功的原因&#xff08;排查&#xff09;&#xff1a;总结前言 网上文章千篇一律&#xff0c;导致很多人都只会一种方法&#xff0c;只要有一种办法就所有人跟着这个办法去做了&#xff0c;新建java文件&#xff0…

Azure Function App Deploy Issue

问题&#xff1a;之前一直用vs code 的 Azure Function extension 工具部署&#xff0c;没有什么问题。直到3月份发现 vs code显示部署成功&#xff0c;但是通过 https://<function_name>.scm.azurewebsites.net/DebugConsole 查看上传后的 dll 文件&#xff0c;dll文件根…

每日学术速递3.8

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Unleashing Text-to-Image Diffusion Models for Visual Perception 标题&#xff1a;释放用于视觉感知的文本到图像扩散模型 作者&#xff1a;Wenliang Zhao, Yongming Rao, Zuya…

【maven 学习记录】

maven 学习记录一、maven基础1. maven是什么2. maven的作用3. maven的下载安装4. maven仓库5. maven坐标6. 第一个maven项目 手工实现7. maven插件8. 依赖管理9. 生命周期二、maven进阶一、maven基础 1. maven是什么 maven的本质是一个项目管理工具&#xff0c;将项目开发和管…