如何使用 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";
// ...


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



相关文章
|
2月前
|
缓存 前端开发 JavaScript
利用代码分割优化前端性能:策略与实践
在现代Web开发中,代码分割是提升页面加载性能的有效手段。本文介绍代码分割的概念、重要性及其实现策略,包括动态导入、路由分割等方法,并探讨在React、Vue、Angular等前端框架中的具体应用。
|
3月前
|
数据可视化 算法 Python
基于OpenFOAM和Python的流场动态模态分解:从数据提取到POD-DMD分析
本文介绍了如何利用Python脚本结合动态模态分解(DMD)技术,分析从OpenFOAM模拟中提取的二维切片数据,以深入理解流体动力学现象。通过PyVista库处理VTK格式的模拟数据,进行POD和DMD分析,揭示流场中的主要能量结构及动态特征。此方法为研究复杂流动系统提供了有力工具。
173 2
基于OpenFOAM和Python的流场动态模态分解:从数据提取到POD-DMD分析
|
3月前
|
前端开发 JavaScript 开发者
利用代码分割优化前端性能:高级技巧与实践
【10月更文挑战第2天】在现代Web开发中,代码分割是优化前端性能的关键技术,可显著减少页面加载时间。本文详细探讨了代码分割的基本原理及其实现方法,包括自动与手动分割、预加载与预取、动态导入及按需加载CSS等高级技巧,旨在帮助开发者提升Web应用性能,改善用户体验。
|
6月前
|
图形学 开发者
U3D开发进阶:精细调整Collider与优化碰撞检测性能
【7月更文第11天】在Unity 3D(简称U3D)开发过程中,精确控制Collider(碰撞器)的设置与合理利用Layer Collision Matrix(层级碰撞矩阵)对于提升游戏性能、优化物理模拟至关重要。本文将深入探讨这两项技术的应用,通过实际案例和代码示例,帮助开发者构建更加高效、流畅的游戏体验。
764 2
|
8月前
|
缓存 算法 计算机视觉
OpenCV图像处理-视频分割静态背景-MOG/MOG2/GMG
1.概念介绍 视频背景扣除原理:视频是一组连续的帧(一幅幅图组成),帧与帧之间关系密切(GOP/group of picture),在GOP中,背景几乎是不变的,变的永远是前景。
350 0
|
数据处理 计算机视觉 Python
图像数据处理:基本技巧与实例分析
图像数据处理:基本技巧与实例分析
216 0
|
机器学习/深度学习 自然语言处理 算法
文本数据处理:基本技巧与实例分析
文本数据处理:基本技巧与实例分析
469 0
|
计算机视觉
当「分割一切」遇上图像修补:无需精细标记,单击物体实现物体移除、内容填补、场景替换(1)
当「分割一切」遇上图像修补:无需精细标记,单击物体实现物体移除、内容填补、场景替换
160 0
|
人工智能 编解码 移动开发
当「分割一切」遇上图像修补:无需精细标记,单击物体实现物体移除、内容填补、场景替换(2)
当「分割一切」遇上图像修补:无需精细标记,单击物体实现物体移除、内容填补、场景替换
136 0