写点什么

【得物技术】JS 资源分包

用户头像
得物技术
关注
发布于: 2021 年 06 月 04 日

背景

在版本更新迭代、新代码上线后,如果用户需要重新从服务器加载全部资源(js、css),肯定会让页面打开变慢,这其实是没有必要的。

为了优化用户体验,提高页面打开速度,可以将 js 拆分成多个模块,每次有更新,用户只需要加载更新了的业务代码即可,这就是分包。

方案

一般来说,前端项目不管框架是什么,大多是基于 webpack 打包的,比如 umi、next、nuxt、vue-cli,所以本文只基于 webpack 打包工具给出方案。

webpack4 提供了 splitChunks 插件,就是用来做代码分割的,具体使用方法可以查看官方文档。

比较普遍的分包策略是按照体积大小、共用率、更新频率重新划分我们的包,使其尽可能的利用浏览器缓存。

根据这一策略给出通用的分包方案,将 js 拆分成以下三个模块:

  1. 第三方依赖(node_modules)

  2. UI 库(antd、element-ui、cube-ui)

  3. 业务代码

因此,每次发布代码之后通常需要更新的只有 3、而 1 和 2 直接从浏览器缓存中读取即可。

实施

以 phoenix 项目为例,目前的线上页面打包后的情况如下图:

通过分析工具看看各个模块是什么:


  • umi.js:框架 js

  • verdors.async.js:第三方依赖

  • layouts_index.async.js 和 p_discountDetail_index.async.js:业务代码

  • (忽略 bundle.min.js,这是 sentry 脚本)

在什么都不做的情况下 umi 其实已经默认分包了,这是因为其内置的 webpack 提供了默认分包策略:

  • 新的 chunk 是否被共享或者是来自 node_modules 的模块

  • 新的 chunk 体积在压缩之前是否大于 30kb

  • 按需加载 chunk 的并发请求数量小于等于 5 个

  • 页面初始加载时的并发请求数量小于等于 3 个

使用上述方案对默认分包策略进行优化,将 UI 库提取出来,在配置文件(umirc.ts)中加入自定义分包代码:

config.optimization.splitChunks({  chunks: 'async',  minSize: 30000,  maxSize: 0,  minChunks: 1,  maxAsyncRequests: 5,  maxInitialRequests: 3,  automaticNameDelimiter: '~',  name: true,  cacheGroups: {  	vendors: {    	name: 'vendors',      test: /[\\/]node_modules[\\/]/,        priority: -10,		},    antdesigns: {      name: 'antdesigns',      test: /[\\/]node_modules[\\/]antd-mobile[\\/]/,      priority: -9,		}  }})复制代码
复制代码

各个字段的表示的含义不再此赘述,可查看官方文档。主要看 cacheGroups,把 antd 提取了出来。

再来看下打包之后的效果:


多了一个 antdesigns.js,成功将 antd 提取出来。


Q:其实这里可以思考一下,将 antd 提取到底合不合适?

A:phoenix 项目是个多页面应用,目前页面数量不多,而 antd 也支持按需引入,将 antd 代码打包进各个页面的业务代码或者 node_modules 中也不会增加多少体积,而 antd 代码体积并不大,单独提取出来后需要多一次 http 链接,感觉没有必要。不过随着以后项目体积变大,也就不一定了。所以各个项目还是要根据自身情况进行分包。

结论

分包是一个博弈的过程,是让 a bundle 大一点还是 b?

是让首次加载快一点还是让 cache 的利用率高一点?

但有一点要切记,拆包的时候不要过分的追求颗粒化,什么都单独的打成一个 bundle,不然你一个页面可能需要加载十几个 js 文件,如果你还不是 HTTP/2 的情况下,请求的阻塞还是很明显的(受限于浏览器并发请求数)。

所以还是那句话资源的加载策略并没什么完全的方案,都需要根据项目自身情况进行分包。

后续要做的

分包之后的下一步就是充分使用浏览器缓存,首先需要把静态资源放到 cdn 上,再设置合理的缓存策略,只要 chunk 的 hash 没有改变,都从浏览器缓存读取。

参考资料:panjiachen.github.io/awesome-boo…


文/小辰

关注得物技术,携手走向技术的云端


发布于: 2021 年 06 月 04 日阅读数: 20
用户头像

得物技术

关注

得物APP技术部 2019.11.13 加入

关注微信公众号「得物技术」

评论

发布
暂无评论
【得物技术】JS资源分包