如何使用 splitChunks 精细控制代码分割(上)

简介: 前端小伙伴都知道,为了降低包大小,经常会把依赖的前端模块独立打包,比如把 vue、vue-router 打到一个单独的包 vendor 中。另外,常会将存在多个路由的复杂页面的每个页面都单独打一个包,只有访问某个页面的时候,再去下载该页面的js包,以此来加快首页的渲染。无论是 react 还是 vue 都提供了完善的工具,帮我们屏蔽了繁琐的配置工作。当我们对代码进行构建时,已经自动帮我们完成了代码的拆分工作。所以,很多小伙伴并不知道背后到底发生了什么事。至于为什么这么拆分,到底如何控制代码的拆分,更是一头雾水了。

问题测验


讲解开始之前,大家先看一个问题。如果你已经知道问题的答案,而且明白为什么,就不必往下阅读了。如果不知道答案或者知道答案,但不知道原因。那么,强烈建议阅读本文。


// webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  entry: { app: "./src/index.js" },
  output: {
    filename: "[name].js",
    path: path.resolve(__dirname, "dist")
  },
  optimization: {
    splitChunks: {
      chunks: "all"
    }
  },
  plugins: [
    new HtmlWebpackPlugin()
  ]
};


// index.js
import "vue"
import(/*webpackChunkName: 'a' */ "./a");
import(/*webpackChunkName: 'b' */ "./b");


// a.js
import "vue-router";
import "./someModule"; // 模块大小大于30kb


// b.js
import "vuex";
import "./someModule"; // 模块大小大于30kb


// someModule.js
// 该模块大小超过30kb
// ...


代码分割的三种方式


webpack 中以下三种常见的代码分割方式:


  • 入口起点:使用 entry 配置手动地分离代码。


  • 动态导入:通过模块的内联函数调用来分离代码。


  • 防止重复:使用 splitChunks 去重和分离 chunk。 第一种方式,很简单,只需要在 entry 里配置多个入口即可:


entry: { app: "./index.js", app1: "./index1.js" }


第二种方式,就是在代码中自动将使用 import() 加载的模块分离成独立的包:


//...
import("./a");
//...


第三种方式,是使用 splitChunks 插件,配置分离规则,然后 webpack 自动将满足规则的 chunk 分离。一切都是自动完成的。


前两种拆分方式,很容易理解。本文主要针对第三种方式进行讨论。


splitChunks 代码拆分


splitChunks 默认配置


splitChunks: {
    // 表示选择哪些 chunks 进行分割,可选值有:async,initial和all
    chunks: "async",
    // 表示新分离出的chunk必须大于等于minSize,默认为30000,约30kb。
    minSize: 30000,
    // 表示一个模块至少应被minChunks个chunk所包含才能分割。默认为1。
    minChunks: 1,
    // 表示按需加载文件时,并行请求的最大数目。默认为5。
    maxAsyncRequests: 5,
    // 表示加载入口文件时,并行请求的最大数目。默认为3。
    maxInitialRequests: 3,
    // 表示拆分出的chunk的名称连接符。默认为~。如chunk~vendors.js
    automaticNameDelimiter: '~',
    // 设置chunk的文件名。默认为true。当为true时,splitChunks基于chunk和cacheGroups的key自动命名。
    name: true,
    // cacheGroups 下可以可以配置多个组,每个组根据test设置条件,符合test条件的模块,就分配到该组。模块可以被多个组引用,但最终会根据priority来决定打包到哪个组中。默认将所有来自 node_modules目录的模块打包至vendors组,将两个以上的chunk所共享的模块打包至default组。
    cacheGroups: {
        vendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10
        },
        // 
    default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true
        }
    }
}


以上配置,概括如下4个条件:


  1. 模块在代码中被复用或者来自 node_modules 文件夹


  1. 模块的体积大于等于30kb(压缩之前)


  1. 当按需加载 chunks 时,并行请求的最大数量不能超过5


  1. 初始页面加载时,并行请求的最大数量不能超过将3


// index.js
import("./a");
// ...


// a.js
import "vue";
// ...


以上代码,在默认配置下的构建结果如下:



相关文章
|
6月前
|
算法
【MFAC】基于全格式动态线性化的无模型自适应控制
【MFAC】基于全格式动态线性化的无模型自适应控制
|
1月前
|
数据可视化 算法 Python
基于OpenFOAM和Python的流场动态模态分解:从数据提取到POD-DMD分析
本文介绍了如何利用Python脚本结合动态模态分解(DMD)技术,分析从OpenFOAM模拟中提取的二维切片数据,以深入理解流体动力学现象。通过PyVista库处理VTK格式的模拟数据,进行POD和DMD分析,揭示流场中的主要能量结构及动态特征。此方法为研究复杂流动系统提供了有力工具。
70 2
基于OpenFOAM和Python的流场动态模态分解:从数据提取到POD-DMD分析
|
21天前
|
编解码 人工智能 开发者
长短大小样样精通!原始分辨率、超长视频输入:更灵活的全开源多模态架构Oryx
【10月更文挑战第23天】Oryx 是一种新型多模态架构,能够灵活处理各种分辨率的图像和视频数据。其核心创新在于能够对图像和视频进行任意分辨率编码,并通过动态压缩器模块提高处理效率。Oryx 在处理长视觉上下文(如视频)时表现出色,同时在图像、视频和3D多模态理解方面也展现了强大能力。该模型的开源性质为多模态研究社区提供了宝贵资源,但同时也面临一些挑战,如选择合适的分辨率和压缩率以及计算资源的需求。
28 3
|
1月前
|
前端开发 JavaScript 开发者
利用代码分割优化前端性能:高级技巧与实践
【10月更文挑战第2天】在现代Web开发中,代码分割是优化前端性能的关键技术,可显著减少页面加载时间。本文详细探讨了代码分割的基本原理及其实现方法,包括自动与手动分割、预加载与预取、动态导入及按需加载CSS等高级技巧,旨在帮助开发者提升Web应用性能,改善用户体验。
|
2月前
|
自然语言处理 测试技术
明确了:文本数据中加点代码,训练出的大模型更强、更通用
【9月更文挑战第18天】《To Code, or Not To Code? Exploring Impact of Code in Pre-training》一文探讨了在大型语言模型(LLMs)预训练中引入代码数据的影响。研究显示,包含代码数据能显著提升模型的总体性能,尤其在自然语言推理和代码任务上表现突出。作者通过广泛的消融实验验证了这一结论,但同时也指出需关注潜在的负面效应及模型架构等因素的影响。更多详细信息,请参阅论文原文:[链接](https://arxiv.org/abs/2408.10914)。
56 10
|
6月前
|
机器学习/深度学习 计算机视觉 网络架构
【FCN】端到端式语义分割的开篇之作! 从中窥探后续语义分割网络的核心模块(一)
【FCN】端到端式语义分割的开篇之作! 从中窥探后续语义分割网络的核心模块(一)
411 0
【FCN】端到端式语义分割的开篇之作! 从中窥探后续语义分割网络的核心模块(一)
|
6月前
|
算法
【MFAC】基于紧格式动态线性化的无模型自适应迭代学习控制
【MFAC】基于紧格式动态线性化的无模型自适应迭代学习控制
【MFAC】基于紧格式动态线性化的无模型自适应迭代学习控制
|
机器学习/深度学习 数据采集 PyTorch
图片风格自动分析模型
图片风格自动分析模型
214 0