结合Next项目实际认识webpack.splitChunks

本文的目的在于简单的介绍webpack的优化功能配置:splitChunks
webpack5出于“开箱即用”的目的,将大部分曾经要使用插件的功能集成到了config配置中,因此用户只需要了解如何配置,即可达到优化目的,其中最常使用接触的配置是:webpack.optimization.splitChunks。

一、拆分方法的比较

参考:
Webpack常用知识点
说到拆分,往往我们会有以下几个选择:
动态引入:import('')webpack.entry配置多个入口splitChunks拆分抽取公共代码
相比较而言:

  1. 动态引入的拆分需要对一个个文件单独处理,不能整体规划,更适合写代码时考虑。
  2. 配置多个入口,大多时候没有此必要,而且容易将公共模块重复打包,拆分策略不一定好。
  3. splitChunks拆分:1. 配置在打包时,开发过程中可以不考虑。2. 可以整体考虑公共代码,比如react / utils等公共包。3. 使用webpack-analyze有利于更具体看到打包后的效果。

二、如何使用

webpack官方文档
详解利用webpack的splitChunk拆分打包文件

splitChunks中提供了一些字段,常用的有下列属性(其他属性大多时候不需改动):

chunks

分为all(推荐)|async(默认)|initial ,区别在于打包时模块的合并策略。

  1. all:推荐,不论是同步引入还是异步引入,都会被合并打包。
  2. async:和目前我们不设置任何配置的情况相同,同步引入的模块会被一起打包,而动态进入的模块是自动拆分到另一个包中。
  3. initial:同步引入的模块会被合并抽取成新的包,而异步引入的代码会被拆分成另一个包,比如a.js和b.js一个动态引入react,一个同步引入react,这时候打包出来的就是vendors-react(同步)、react(异步)两个react包而不会合并,这样就造成了浪费。

minSize

最小尺寸,默认是30K,development 下是10k,设置的越大满足该尺寸的chunk 数就会变少(针对于提取公共 chunk 的时候,不管再大也不会把动态加载的模块合并到初始化模块中),当这个值很大的时候就不会做公共部分的抽取了。

minChunks

如果一个模块被多个chunk所引用的次数达到了minChunks指定的次数,那么这个模块就会被打包成一个单独的chunk。但是因为我们的项目只有一个入口文件,Webpack只会生成一个chunk,这时minChunks就没有作用了,因为打包结果只有一个chunk,不需要进行代码分离。

maxInitialRequests

参考:https://www.cnblogs.com/kwzm/p/10316217.html
maxInitialRequests是splitChunks里面比较难以理解的点之一,它表示允许【单个】入口并行加载的最大请求数,之所以有这个配置也是为了对拆分数量进行限制,不至于拆分出太多模块导致请求数量过多而得不偿失。

这里需要注意几点:

  1. 入口文件本身算一个请求
  2. 如果入口里面有动态加载得模块这个不算在内
  3. 通过runtimeChunk拆分出的runtime不算在内
  4. 只算js文件的请求,css不算在内
  5. 如果同时又两个模块满足cacheGroup的规则要进行拆分,但是maxInitialRequests的值只能允许再拆分一个模块,那尺寸更大的模块会被拆分出来

cacheGroups

cacheGroups(缓存组)是 webpack splitChunks 最核心的配置,splitChunks的配置项都是作用于cacheGroup上的,也就是cacheGroups缓存组可以继承和覆盖来自 splitChunks.* 的任何选项。
接下来我们也是主要使用这个配置去拆分合并代码。

priority

拆分优先级,webpack首先会遍历依赖,生成依赖树,然后对单个模块打包,最后再拆分合并。这个属性可以决定一个模块同时属于多个合并规则的时候将合并进哪个文件内。

reuseExistingChunk

如果该chunk包含的modules都已经另一个被分割的chunk中存在,那么直接引用已存在的chunk,不会再重新产生一个

test

当test为函数时,返回true/false,并且接收两个参数:module和chunks
module:每个模块打包的时候,都会执行test函数,并且传入模块 module 对象,module 对象包含了模块的基本信息,例如类型、路径、文件 hash 等;
chunks:是当前模块被分到哪些chunks使用,module 跟 chunks 关系可能是一对一或者多对一。

module.exports = {//...optimization: {splitChunks: {cacheGroups: {vendors: {test(module, chunks) {//...return module.type === 'javascript/auto';}}}}}
};

三、具体实现

修改完配置之后,我们可以通过webpack-analyze看到打包出来的具体效果,衡量自己的优化程度。
在next中,就是如下配置:

const withBundleAnalyzer = require('@next/bundle-analyzer')({enabled: process.env.ANALYZE === 'true',
});module.exports = withTM(withBundleAnalyzer(withImages(withAntdLess(nextConfig))));npm run analyzer

一般而言,没有改动过的Next自带的配置如下:(从next.config中打印出来的数据)

{emitOnErrors: true,checkWasmTypes: false,nodeEnv: false,splitChunks: {chunks: [Function: chunks],cacheGroups: { {framework: {chunks: 'all',name: 'framework',test: [Function: test],priority: 40,enforce: true},lib: {test: [Function: test],name: [Function: name],priority: 30,minChunks: 1,reuseExistingChunk: true} },maxInitialRequests: 25,minSize: 20000},runtimeChunk: { name: 'webpack' },minimize: true,minimizer: [ [Function (anonymous)], [Function (anonymous)] ]
}

想要增加分包策略,只需要像如下代码,在next暴露出的config中配置

  webpack(config, { webpack, isServer }) {try {if (!isServer) {const cacheGroups = config.optimization.splitChunks.cacheGroups;console.log(cacheGroups)}} catch (e) {console.error('webpack cacheGroups error: ',e);}return config;}

我的主要目的在于优化项目的首包,也就是app.js,所以主要查看的也是这个包。
首先打印出项目的打包文件如图:(假装有图)
 
分析也许是受限于:maxInitialRequests,或者其他的原因,react / mobx等包都没有拆分出app的包,须知,这种固定依赖往往可以放在CDN中很久不变动,要是每次都跟着app包重新下载,不利于CDN利用和首屏渲染。
故第一份优化配置如下:
拆分公共依赖库:antd / mobx / react / moment / lodash等等,当然后续还可以拆分其他的模块。

 const cacheGroups = config.optimization.splitChunks.cacheGroups;// 1.mobxcacheGroups.antd = {name: 'antd',test: /[\\/]node_modules[\\/](antd|@ant-design)[\\/]/,enforce: true,chunks: 'all',};// 2.工具类cacheGroups.vendors = {name: 'vendors',test: /[\\/]node_modules[\\/](mobx|axios|lodash|moment)[\\/]/,enforce: true,chunks: 'all',priority: 20,};// 3.utils&configcacheGroups.utils = {name: 'utils',test: /[\\/]src[\\/]utils[\\/]/,enforce: true,chunks: 'all',priority: 20,};

拆分后,可见打出来三个新的包antd 、vendors、utils,项目的整体大小少了0.6M,如果觉得antd的包过大,也可以再使用maxSize限制,或者细化test正则。

接下来再分析app的页面,看到某个模块下引入的配置文件基本上占用了一半的大小,这个配置文件是在一个大的activity文件夹下的多个小活动中的config.js。这是因为之前为了在服务器端渲染的时候能够获取到配置数据,所以在_app.js引入造成的问题,随着后续的需求展开,这里的影响可能会越来越大,因此必须得想个办法拆分出去。
想要把这一部分的包拆分出去,一开始考虑了几个方法:

  1. import动态引入分割。
  2. cacheGroup中添加代码分割的规则。(不能直接使用test是因为文件夹下有很多文件,一旦使用test会把所有文件都打包进来,不符合要求)
  3. 把这部分配置集中到另一个文件夹内,这样可以使用test去识别分割。
  4. 以上办法都不行的话,就把配置代码从_app中移出来,放到组件里面去动态处理生成。

方法一:

一开始写了一个类似下方这样的动态引入代码,但是在mobx数据初始化时才会进行下载,无法获取到配置数据。

await ConfigRes.then((Config) => {const ConfigResModule = ConfigRes.default;
});

方法二:

经过尝试最后把test的名称正则改成只识别配置文件夹下的config.js文件。
优先级不能填太高,优先级填的高的话,activity下方所有活动的文件都会被打包进来,有使用和没有使用的文件都放在了一起,这样反而无法达到减负的目的。因此优先级填最低,这样可以使“未被划分进其他包、最后只能留在app.js包”中的这一些activity数据抽取出来。
再做一层保险设置maxSize,以免以后配置了太多活动导致这个包过大。

cacheGroups.activity = {name: 'activity',test: /[\\/]src[\\/]activity[\\/].*[\\/]config.js/,enforce: true,chunks: 'all',priority: -30,maxSize:200000,
};

方法三:

方法二其实比较繁琐,但是这样做可以使开发可以不去关注打包信息,只关注自己要开发的代码,而不用把代码挪过来挪过去。

方法四:

方法二已实现后,暂时没有考虑。

四、数据比对

需要做性能测试。

五、安全考虑

可能要经过压测和稳定性测试,以及性能测试看看是不是真的有效。

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

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

相关文章

Backtrader 文档学习- Observers - Reference

Backtrader 文档学习- Observers - Reference 1.Benchmark class backtrader.observers.Benchmark() 观察器存储策略的回报和参考资产的回报,参考资产是传递给系统的数据之一。 参数: timeframe (default: None) ,如果None,则将…

【ES】--ES集成自定义分词库

目录 一、相关安装1、(window单机)elasticsearch安装2、安装Elasticvue插件3、ik分词器插件4、ES集成自定义词库 一、相关安装 1、(window单机)elasticsearch安装 Win10下下载ES组件,安装部署如下:JDK1.8、elasticsearch-7.3.2-windows-x86_64。 Elast…

Debezium发布历史124

原文地址: https://debezium.io/blog/2022/06/21/debezium-1-9-4-final-released/ 欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯. Debezium 1.9.4.Final Released June 21, 2022 by Chris Cranford …

qt “美颜”

要想成为一名优秀的qt工程师 学会使用qss编程也是重要的 不可获缺的一部分 qss 简介和优势 QSS(Qt Style Sheets)是一种用于定义Qt应用程序界面外观和样式的样式表语言。它类似于CSS(层叠样式表),但针对Qt框架进行了定…

末两位数(1992)_题解

【题解提供者】吴立强 解法 思路 指数函数增长速率过快,直接计算中间过程任何一种基本类型都无法存储。 通过乘法运算的规律,可以发现末两位数只和末两位数相关,故直接对中间结果保留末两位数(mod 100)即可避免乘法…

每日五道java面试题之java基础篇(七)

第一题. HashMap和HashTable有什么区别?其底层实现是什么? 区别 : HashMap⽅法没有synchronized修饰,线程⾮安全,HashTable线程安全;HashMap允许key和value为null,⽽HashTable不允许 底层实现…

容器高级知识: 适配器模式与 Sidecar 模式的区别

适配器模式与 Sidecar 模式的区别 在 Kubernetes 中,适配器模式和 Sidecar 模式都是扩展您的主应用程序容器功能的方法,但它们具有不同的目的和功能: Sidecar 模式: 通用目的: 为主应用程序提供 补充功能&#xff0…

(十五)springboot实战——spring securtity的核心过滤器介绍

前言 本节内容主要介绍spring securtity安全框架的一些核心过滤器及其作用,我们都清楚spring securtity安全框架底层是基于filter过滤器实现的,采用的是责任链的设计模式,它有一条很长的过滤器链。本次spring securtity原理介绍使用的版本是…

H12-821_31

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

Android13多媒体框架概览

Android13多媒体框架概览 Android 多媒体框架 Android 多媒体框架旨在为 Java 服务提供可靠的接口。它是一个系统,包括多媒体应用程序、框架、OpenCore 引擎、音频/视频/输入的硬件设备,输出设备以及一些核心动态库,比如 libmedia、libmedi…

探索Gorm - Golang流行的数据库ORM框架

🏷️个人主页:鼠鼠我捏,要死了捏的主页 🏷️系列专栏:Golang全栈-专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 前些天发现了一个巨牛的人工智能学习网站,通俗易懂&…

14.7 OpenGL图元装配和光栅化:早期各片段测试

早期各片段测试 Early Per-Fragment Tests layout(early_fragment_tests) in; 如果片段着色器指定了 Early_fragment_tests 布局限定符,则将在片段着色器执行之前执行本节中描述的每个片段测试。 否则,它们将在片段着色器执行后执行。在光栅化阶段生成片…

自动化测试工具

自动化测试工具有很多种,比如: Appium 。Appium是一个移动端自动化测试开源工具,支持iOS和Android平台,支持Python、Java等语言,即同一套Java或Python脚本可以同时运行在iOS和Android平台。 Appium是一个开源测试自动…

8个Python编程进阶常用技巧!

前言 介绍 Python 炫酷功能(例如,变量解包,偏函数,枚举可迭代对象等)的文章层出不穷。但是还有很多 Python 的编程小技巧鲜被提及。因此,本文会试着介绍一些其它文章没有提到的小技巧,这些小技…

多态

多态的基本语法 多态分为两类 静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名动态多态: 派生类和虚函数实现运行时多态 静态多态和动态多态区别: 静态多态的函数地址早绑定 - 编译阶段确定函数地址动态多态的函数地址晚绑定 - 运行阶段确…

中科大计网学习记录笔记(十):P2P 应用

前言: 学习视频:中科大郑烇、杨坚全套《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》课程 该视频是B站非常著名的计网学习视频,但相信很多朋友和我一样在听完前面的部分发现信…

Centos7离线安装MySQL5.7

卸载mariadb rpm -e --nodeps mariadb-libs可以使用rpm -qa|grep mariadb命令检测是否卸载完成。 关闭selinux 将/etc/selinux/config文件中的SELINUX设置为disabled下载MySql的相关rpm包 打开https://dev.mysql.com/downloads/mysql/ 选择Red Hat Enterprise Linux / Oracle L…

Linux 终端入门

简介 这个教程是 Linux 基础知识系列中的第一篇,涵盖了如何开始使用终端、Linux 命令行以及执行命令。如果你是 Linux 新手,你需要熟悉终端,因为它是与 Linux 服务器交互的标准方式。 这个教程是针对 Ubuntu 22.04 服务器编写的&#xff0c…

离散数学截图

二元运算及其性质 二元运算中的特殊元 半群和独异点 代数系统的同态与同构 下确界是最大的下界,而在4、5、6三个下界里面,4和5都比6大。可4和5之间没办法分出大小,所以这个哈斯图没有下确界

操作系统面试问题——说一下什么是零拷贝?

零拷贝是一种IO操作优化技术,主要用于减少CPU在用户态和内核态之间的上下文切换次数以及减少数据拷贝次数,可以显著提高数据传输的效率。 传统的拷贝方式需要频繁的切换状态,读数据时需要将数据从硬盘加载到内核缓冲区,再从内核缓…