字节小程序
开发者社区
小程序小游戏
登录
【技术攻略】小程序之流加载

【技术攻略】小程序之流加载

1526浏览作者: eiheieihei

一、流加载是什么?

用一句话来解释【流加载】,那就是“下载程序包的同时加载包内的文件”,下载与加载并发可以加速小程序首次无缓存启动的时间。

二、实现方案

1.1 使用pkg包替代zip包

在【流加载方案】之前,小程序的文件都是压缩到zip包内的,尽管zip包的体积更小,但zip包内的文件需要等完整的zip包下载好后才能解压出来使用,解压也需要时间。

在【流加载方案】中,我们改用pkg包来装载小程序的文件,pkg包是未压缩过的二进制文件包,可以直接读取包内指定区域的二进制数据。pkg包相比于压缩的zip包体积会更大,通过开启CDN智能压缩服务,在pkg包请求过程中,服务器对返回的pkg数据进行gzip编码,压缩重复的字符串等,可以减少pkg包的传输大小,从而缩短下载时间。

下图可见pkg包内的文件分布结构,仅举例,不同的小程序文件顺序可能不同。


| 文件标识符"PKG"(8字节) | 文件版本号(8字节) |
| 扩展信息长度(8字节) | 扩展信息 |
| 所包含的文件数量(8字节)| 
| 文件 1 文件名长度(2字节) | 文件 1 文件名 | 文件 1 偏移量(4字节) | 文件 1 大小(4字节) |
| 文件 2 文件名长度(2字节) | 文件 2 文件名 | 文件 2 偏移量(4字节) | 文件 2 大小(4字节) |
| ... |
| 文件 1 二进制内容 | 文件 2 二进制内容 | ... |


1.2 资源加载时机提前

在pkg格式程序包的支持下,我们不必等待包下载完成后才去加载资源,资源加载的时机得以提前。

流加载优化前后的启动阶段流程分别如下:

meta信息获取



下载zip包



解压zip包



加载文件渲染出首帧


meta信息获取



下载pkg包



加载文件并渲染出首帧

假设某个版本的小程序A在改造前后包内文件不变,资源加载顺序相同,提前加载文件可以使得小程序首屏渲染更快出现。


1.3 小程序包体改造优化

包体改造主要是优化小程序的首屏加载时间,把app-service.js进行拆分,把小程序不同界面的js逻辑从app-service.js文件中拆分出来, 各界面打开时再按需加载,减少了首屏加载过程中所需要加载的内容,可缩短首屏展示时间。

如下图所示,拆分前,app-service.js包含拆出来的pageA、pageB、pageC的js逻辑。拆分后,首屏仅需要下载完“瘦身后”的app-service.js以及首页pageA.js再加载即可。


1.4 pkg文件顺序重排优化

为了达到流加载的最大收益,我们还做了【pkg包中文件分布顺序的优化】。

举个例子,如下是某个小程序pkg包文件分布图,从低到高位分别安放着以下文件:


当小程序启动后,pkg下载的大小刚好包含game.js文件,于是小程序开始加载执行game.js, 但game.js中又去加载了gameB.js,这种情况下,小程序就会停止执行,等待pkg继续下载,直到包下载大小超过了gameB.js才会继续执行。

【pkg包内文件分布顺序】的优化就是为去调整文件在pkg包中的坐落位置,尽可能让文件分布顺序与小程序启动执行要加载的文件顺序一致。这样就可以减少在启动无缓存小程序的过程中, 出现要加载某个尚未下载到的文件而停止等待的场景。

后台每日根据上报的文件访问顺序埋点,按顺序以及频率进行排序,优化pkg的文件顺序,生成新的pkg。该操作无需开发者做任何操作。

最后一次编辑于 2022年02月28日
加载中