Code Splitting 是什么?
代码分割 Code Splitting 是一种优化技术,可独立将较大的文件提取分割为一个文件,然后按需加载这些部分。这种技术主要用于 Web 应用程序,改善应用程序的加载性能和用户体验,
未使用 Code Splitting 造成的影响
在 Web 项目中,通常会将三方依赖与逻辑之类文件打包为一个或多个JS文件,从而导致用户首次访问 Web 应用时会一次性将全部文件请求并进行缓存,虽然后续的请求会相对首次快很多,但仍然存在性能问题,当然这些问题时在项目体积较大时才有感知。
1. 用户首次访问速度较慢
项目上线后,新用户首次访问速度过慢,造成此问题原因,为用户第一次访问会在项目初始化的时候将引入的资源全部请求并缓存,项目体积较大时,例如一个大依赖大小为2M,存在 10 ~ 20 上不封顶,一次性加载性能问题也就可想而知有多慢,如下图(简单图)。
如下图为未进行分割打包后的统计图,可以看到所有依赖及逻辑代码都在一个文件内
打完的包总共也才 9M,一个 ElementPlus 占 近 2M,当项目依赖较多,占比有大半及以上。
2. 更新部署重新请求并缓存
与第一问题类似,当我们业务代码有变更时,需重新打包部署,但依赖并没有变化,项目打包是将所有业务代码与依赖打包成一个文件,部署后客户端缓存机制发现有变化,就会重新加载并缓存。
3. 组件引入依赖加载整个文件
以 ElementPlus 举例,未对其分割,当 A、B、C 组件访问会重新加载整个 JS 文件,首次为请求资源,后续则为缓存资源,如下图。
以上为弊端,归根结底还是时间问题,性能好时间快,则反之
使用 Code Splitting 的优势
减少初始加载时间
通过将代码拆分为较小的模块,可以将用户需要的代码延迟加载到其实际需要时。这意味着初始页面加载时间更短,用户可以更快地看到页面内容 ,如下图。
优化带宽利用
减少初始加载时间不仅使用户更快地看到页面内容,还可以提高整体性能。较小的初始包意味着更快的页面渲染速度和更快的交互响应时间
更好的性能
拆分代码可以根据不同页面或功能的需求动态加载所需的代码块。这样,如果用户只访问页面的一部分,就不必下载整个应用程序的代码,如下图。
提高缓存效率
浏览器可以更有效地缓存已经加载的代码块。在用户再次访问站点时,只需下载新内容,而不是整个应用程序
使用 Code Splitting 进行分割
这里以作者项目举例,vue.config 文件配置 configureWebpack,多种配置方式
config
const { defineConfig } = require('@vue/cli-service')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = defineConfig({
publicPath: './',
lintOnSave: false,
transpileDependencies: true,
// 样式解析
css: {
extract: true
},
// webpack errors 提示清除
devServer: {
port:8089,
client: {
overlay: false,
},
},
configureWebpack: {
entry: { app: './src/main.ts', },
plugins: [ new BundleAnalyzerPlugin() ],
// 代码单独分割
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
elementUI: {
// 文件名称
name: 'element-ui',
// 权重
priority: 20,
// 匹配地址
test: /[\\/]node_modules[\\/](element-plus|@element-plus)[\\/]/,
},
},
},
},
},
chainWebpack: config => {
config.module
.rule('js')
.use('thread-loader')
.loader('thread-loader')
.end()
}
})
以上简单举例,配置 将 ElementPlus 单独打包一个文件,如下。
以下为分割后分析图
可以看到业务代码中已不包含任何与 element-plus 相关代码了~,一切不常改动内容都可以采用 Code Splitting 对其进行分割,如项目内的封装组件等。