webpack 之 splitChunks分包策略

webpack 之 splitChunks分包策略

  • 一、为什么需要拆包
  • 二、拆包方式
  • 三、splitChunks介绍
  • 四、splitChunks 拆包策略
  • 五、总结

一、为什么需要拆包

随着应用程序规模的增长,JavaScript 文件的大小也越来越大。一个大的 JavaScript 文件会导致页面加载时间过长,影响用户体验。良好的拆包策略可以将一个大的 JavaScript 文件分割成多个较小的代码块,将公用的代码抽离成单独的 chunk,在需要的时候按需加载,并充分利用浏览器的缓存机制,如果使用合理,会极大影响加载时间。

二、拆包方式

  1. 入口起点(entry )
    通过使用入口起点的方式,可以将代码分离成多个单独的文件,这些文件可以通过 webpack 配置一个数组结构的 entry 选项指定。并且在其中传入不同类型的文件,可以实现将 CSS 和 JavaScript(和其他)文件分离在不同的 bundle。但是,这种方式有一些缺点,如无法动态加载,无法共享模块等。
  2. 代码分离(Code Splitting)
    代码分离指将代码分成不同的包/块,然后可以按需加载,而不是加载包含所有内容的单个包。用户只需要下载当前他正在浏览站点的这部分代码,代码分离可以使用ES6模块中的 import() 函数动态的加载模块。使用动态导入的模块会被分割到一个单独的 chunk 中。
  3. 打包分离(Bundle Splitting)
    webpack 为单个应用程序生成多个 bundle 文件。如果你有一个体积巨大的文件,并且只改了一行代码,用户仍然需要重新下载整个文件。但是如果你把它分为了两个文件,那么用户只需要下载那个被修改的文件,而另一个文件浏览器可以从缓存中加载,从而减少重新发布并由此被客户端重新下载的代码量。

综上所述,合理的拆包策略可以显著提升应用程序的性能。代码分离通过将代码按需加载,减小初始下载量;而打包分离将应用程序拆分成多个块,实现增量更新,减少不必要的下载。根据具体场景和需求,选择合适的拆包方式可以最大程度地优化应用程序的加载性能。

三、splitChunks介绍

splitChunks 将满足拆分规则的构建内容抽出来单独打包,从而达到抽离公共模块,减少重复打包的目的。splitChunks 中的配置项用来确定具体的拆分规则,其中的 cacheGroups 配置项必须同时满足其下的所有条件才能生效。

webpack5 中 splictChunks 的默认配置为:

module.exports = {optimization: {splitChunks: {chunks: 'async',// 生成的 chunk 的最小体积,单位为字节(bytes)。内容超过了minSize的值,才会进行打包minSize: 20000,minRemainingSize: 0,// 在拆分之前,必须共享的模块的最小 chunk 数。minChunks: 1,// 在按需加载时,允许的最大并行请求数。maxAsyncRequests: 30,// 入口点允许的最大并行请求数。maxInitialRequests: 30,// 超过这个值就会进行强制分包处理,无视minRemainingSize,maxAsyncRequests,maxInitialRequestsenforceSizeThreshold: 50000,cacheGroups: {vendors: {test: /[\\/]node_modules[\\/]/,priority: -10,// 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块reuseExistingChunk: true,},default: {minChunks: 2,priority: -20,reuseExistingChunk: true,},},},},
};

其中chunks属性可配置值有 all、 async 、 initial ,默认值是 async

  1. async : 异步加载进来的包才会校验分包规则,进行分包抽离。如果动态加载的包也同时引用了其它包且命中分包规则也会被抽离出来。

  2. initial : 表示只从入口模块进行拆分。

  3. all : 表示入口模块和异步加载的模块都要进行拆分。

四、splitChunks 拆包策略

  1. split-by-experience: 根据经验制定的拆分策略,自动将一些常用的 npm 包拆分为体积适中的 chunk。适用于大多数项目。
    如下示例,react、antd 会被包拆分到了单独的chunk,其余三方包会在vendorjs。其余的包也可以配置缓存组。如果拆分力度比较细的话还是需要写上一些缓存组的
splitChunks: {// chunks、minSize、minChunks 将对所有缓存组生效chunks: 'all', // 对所有的chunk进行拆分 minSize: 20000, // 拆分 chunk 的最小体积 20000 bytesminChunks: 2, // 需在两个模块中共享才进行拆分cacheGroups: {vendor: {name: 'vendor', // chunk 的名称 vendortest: /[\\/]node_modules[\\/]/i,	// 匹配node_modules下所有的chunkpriority: 10,	// 优先级10 优先将node_modules下的chunk拆分到vendor组reuseExistingChunk: true, // 重用模块,而不是重新生成enforce: true, // 强制拆分},default: {	// 默认组 非node_modules下的文件块 将执行default缓存组规则reuseExistingChunk: true,priority: -10, // 优先级 -10 enforce: true, // 强制拆分},react: { // react组name: 'react',test: /[\\/]node_modules[\\/]react[\\/]/,	// 匹配node_modules下的react库priority: 20,	// 优先级20 优先将node_modules下的react拆分出去minChunks: 2,reuseExistingChunk: true,},antd: {	// antd组name: 'antd',test: /[\\/]node_modules[\\/]antd[\\/]/,	// 匹配node_modules下的antd库priority: 20,	// 优先级20 优先将node_modules下的antd拆分出去minChunks: 2,reuseExistingChunk: true, // 重用模块,而不是重新生成},}}
  1. split-by-module: 按 NPM 包的粒度拆分,每个 NPM 包对应一个 chunk。
    假如应用程序添加或升级了某个 npm 包,那么 vendor.js 的哈希值将会发生改变,这意味着用户在访问页面时需要重新下载 vendor.js文件。这个时候如果对antd进行了升级或新增/删除了一个antd组件,那么用户不需要重新下载vendor.js文件,而只需要下载antd模块对应的chunk。因为每个chunk都有一个独立的哈希值,当我们对单独的chunk进行修改时,只会影响到对应的chunk文件,而不会影响其他chunk文件。这样就实现了对npm包的增量更新。
    这种情况下如果npm包比较多的情况下,会产生高并发请求。对于支持http2的浏览器是没有问题的。但是浏览器并不支持http2的话,也就是http1.1会存在对头阻塞的问题。不过http2兼容性挺好的
splitChunks: {chunks: 'all',enforceSizeThreshold: 50000,cacheGroups: {vendors: {priority: -10,test: /[\\/]node_modules[\\/]/,name(module2) {return module2.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)?.[1];},},},minSize: 0,maxInitialRequests: Infinity,},
  1. single-vendor: 将所有 NPM 包的代码打包到一个单独的 chunk 中。
    这种情况的话,只要三方包有改动,文件hash就会改变。如果频繁改动npm包的话,浏览器缓存效率相对较低
 vendor: {name: 'vendor', // chunk 的名称 vendortest: /[\\/]node_modules[\\/]/i,	// 匹配node_modules下所有的chunkpriority: 10,	// 优先级10 优先将node_modules下的chunk拆分到vendor组reuseExistingChunk: true, // 重用模块,而不是重新生成enforce: true, // 强制拆分},
  1. split-by-size:根据模块大小自动进行拆分。
    符合大小范围内的包就会被拆出来
  splitChunks: {chunks: 'all',minSize: 20000, // 20 KBmaxSize: 50000, // 50 KBcacheGroups: {default: {minChunks: 2,priority: -20,reuseExistingChunk: true,},},},

五、总结

要根据业务场景来选择合适的分包策略,拆到什么力度、什么程度需要自己斟酌。要注意拆包之后相同的模块不要被重复打包。

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

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

相关文章

6.8应用进程跨网络通信

《计算机网络》第7版,谢希仁 理解socket通信

成都仅需浏览器即可快速查看的数据采集监控平台!

LP-SCADA数据采集监控平台无需额外客户端,只需要一个标准的Web浏览器,用户可以迅速访问系统并开始使用,同时支持跨平台访问。一个用户可监控多个过程,多个用户可以监控同一过程,真正实现了数据的开放性及过程信号的透明…

基于单片机的多功能计算器的设计与实现电气工程自动化

摘要: 伴随着科技水平的提高,信息化以及自动化技术也被广泛地运用到了国内的各个行业当中,并且取得了良好的成效。 在新时期的大环境下,人们对于电子产中的需求量越来越大,对于各类电子产品的要求也变得日益严格&#…

CVPR2024自动驾驶轨迹预测方向的论文整理

2024年自动驾驶轨迹预测方向的论文汇总 1、Producing and Leveraging Online Map Uncertainty in Trajectory Prediction 论文地址:https://arxiv.org/pdf/2403.16439 提出针对在线地图不确定性带给轨迹预测的影响对应的解决方案。 在轨迹预测中,利用在…

【产品与技术双视角】初创团队利用小程序云基础设施“低成本试错”

文章目录 前言一、产品视角之三大困难二、技术视角之难以抉择三、利用小程序云基础设施“低成本试错” 前言 学生团队和初创团队在没有得到风投之前,想要做出一款产品太难了,难在哪呢?难在没有资源。用最狭隘的视角看这个资源:人…

SSM中小学生信息管理系统-计算机毕业设计源码02677

摘要 随着社会的发展和教育的进步,中小学生信息管理系统成为学校管理的重要工具。本论文旨在基于SSM框架,采用Java编程语言和MySQL数据库,设计和开发一套高效、可靠的中小学生信息管理系统。中小学生信息管理系统以学生为中心,通过…

hitcontraining_uaf

BUUCTF[PWN][堆] 题目:BUUCTF在线评测 (buuoj.cn) 程序del是没有将申请的指针清零,导致可以再次调用输出print。 查看add_note函数:根据当前 notelist 是否为空,来申请了一个8字节的空间将地址(指针)放在notelist[i]中&#xff…

野指针的概念 如果规避野指针

目录 野指针的概念 有关野指针的代码 如何规避野指针 野指针的概念 野指针就是指针指向的位置是不可知的&#xff08;随机的&#xff0c;不正确的&#xff0c;没有明确限制的&#xff09; 有关野指针的代码 指针未初始化&#xff1a; #include<stdio.h> int main…

Linux 永久挂载磁盘

文章目录 前言一、使用步骤1.命令 总结 前言 一、使用步骤 1.命令 第一步&#xff1a;创建挂载点 sudo mkdir /hhkj 第二步&#xff1a;磁盘挂载到挂载点&#xff08;lsblk、lvdisplay&#xff09; sudo mount /dev/sdb2 /hhkj 或者 sudo mount /dev/centos/home /hhkj 第三…

高阶面试-hbase的整理

背景 冷热分离需要用到hbase&#xff0c;冷数据较多&#xff0c;需求&#xff1a; 存放上亿数据支持简单的组合关键字查询存放数据不需要变更 基本存储数据结构 HBase可以被看作是一个稀疏的多维度Map&#xff08;映射&#xff09;&#xff0c;稀疏的、分布式、多维的Map&a…

使用 mongo2neo4j 和 SemSpect 通过各种方式进行图探索

用于可视化和探索每个 MEAN 堆栈背后的数据图的 ETL 您是否正在努力回答有关 MEANS Web 服务数据的紧急问题&#xff1f;哪里有 BI 可以快速回答“上个季度哪些亚洲的artisan.plus 用户触发了订单&#xff1f;”这个问题&#xff0c;而无需编写查询&#xff1f;使用 mongo2neo4…

深度学习每周学习总结N3(文本分类实战:基本分类(熟悉流程)、textCNN分类(通用模型)、Bert分类(模型进阶))

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 0. 总结&#xff1a;1. 前期准备环境安装 2. 文本分类基本流程a. 加载数据b.构建词典c.生成数据批次和迭代器d.定义模型及实例e. 定义…

Linux搭建hive手册

一、将hive安装包上传到NameNode节点并解压 1、删除安装MySQL时的.rpm文件 cd /opt/install_packages/ rm -rf *.rpm 2、将安装包拖进/install_packages目录 3、解压安装包 tar -zxvf apache-hive-3.1.2-bin.tar.gz -C /opt/softs/ 4、修改包名 cd /opt/softs mv apache-…

力扣双指针算法题目:复写零

1.题目 . - 力扣&#xff08;LeetCode&#xff09; 2.解题思路 本题要求就是对于一个数组顺序表&#xff0c;将表中的所有“0”元素都向后再写一遍&#xff0c;且我们还要保证此元素之后的元素不受到影响&#xff0c;且复写零之后此数组顺序表的总长度不可以改变&#xff0c;…

OpenCV 灰度直方图及熵的计算

目录 一、概述 1.1灰度直方图 1.1.1灰度直方图的原理 1.1.2灰度直方图的应用 1.1.3直方图的评判标准 1.2熵 二、代码实现 三、实现效果 3.1直方图显示 3.2 熵的计算 一、概述 OpenCV中的灰度直方图是一个关键的工具&#xff0c;用于分析和理解图像的灰度分布情况。直…

ubuntu 网络常用命令

在Ubuntu中&#xff0c;管理和诊断网络问题时会用到一些常用的命令行工具。以下是一些Ubuntu网络常用的命令&#xff1a; ifconfig (已被ip命令替代&#xff0c;但仍在许多系统中可用): 显示或配置网络接口信息。示例&#xff1a;ifconfig 显示所有网络接口信息。ip: 一个多功…

12 Dockerfile详解

目录 1. Dockerfile 2. Dockerfile构建过程 2.1. Dockerfile编写规则&#xff1a; 2.2. Docker执行Dockerfile的大致流程 2.3. 总结 3. Dockerfile指令 3.1. FROM 3.2. MAINTAINER 3.3. RUN 3.4. EXPOSE 3.5. WORKDIR 3.6. USER 3.7. ENV 3.8. VOLUME 3.9. ADD …

mac 11 变编译安装nginx

mac 11 变编译安装nginx 记录一次安装过程 所需要的包 pcre: https://sourceforge.net/projects/pcre/files/pcre/OpenSSL: https://www.openssl.org/source/Nginx: https://nginx.org/en/download.html如果没有pcre 和Openssl,报错如下 把pcre和Openssl 解压到nginx 目录下…

libiw中的函数说明

打开电脑连接wifi是一件很平常的事情,但这些事情通常都是操作系统下的wifi管理程序替我们完成的,如何在程序中连接指定的wifi其实很少有资料介绍,在网络专栏的文章中,有两篇是关于wfi编程的文章,其中对无线网卡的操作都是通过ioctl()完成的,显得有些繁琐和晦涩,但其实WE…

Stable Diffusion与AI艺术:探索人工智能的创造力

引言 随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;AI艺术逐渐走进了公众视野。尤其是近年来&#xff0c;Stable Diffusion等技术的出现&#xff0c;显著提升了AI在艺术创作领域的表现力和创造力。这篇文章将深入探讨Stable Diffusion技术的工作原理、应…