插件背景
众所周知,web平台加载Bundle避免不了加载庞杂的碎文件,即使带宽再高,数量众多的请求也会拉低资源加载速度。
自然而然,大家都想通过压缩解压的方式来加载资源。Bundle Zipper也就应运而生了。
目前插件已支持2.4.x版本和3.x版本!
技术支撑
jszip
这个npm包详细不少人都很熟悉,它提供了插件中的压缩和解压能力
pwa
官方文档
pwa的概念类似于小程序,只不过一个是基于微信,一个是基于浏览器。
最直观的用途就是:pwa可以让web应用创建一个桌面快捷方式,好处不言而喻。
而背后的价值在于:配合ServiceWorker(下面简称sw),可以自由控制缓存(CacheStorage)
具体细节就不展开了,毕竟主角是下面的ServiceWorker。
ServiceWorker(以下简称sw)
-
拦截请求
sw的存在意义类似于一个本地化的代理服务器,它能够拦截页面的所有请求,自由修改响应内容。
-
建立缓存
caches是类似于localStorage但是又强大得多的工具。caches主要功能就是,将网络请求和响应进行缓存,当然请求和响应也可以是手动建立的,这就为bundle的提前缓存提供了基础。
-
sw如何使用缓存
sw将bundle下载并解压后,遍历bundle所有文件,在caches中一一创建请求响应缓存。
在sw拦截到页面请求时,去caches中匹配请求,如果已有缓存,则直接使用caches中的缓存,省去了网络请求。
插件做了哪些工作?
-
压缩Bundle
-
压缩js文件(3.x的功能)
-
将sw注入到index.html,无缝衔接原有游戏加载流程
-
构建完成时自动打包好发布包
使用要求
-
只支持H5 (HTTPS)
-
构建时必须勾选【MD5 Cache】
加速原理
启动加速
通过指定插件配置的初始化Bundle,sw会在游戏加载之前下载好指定的所有Bundle并缓存。
对于需要在进入游戏大厅之前就就需要加载的那些Bundle,比较适合配置在【初始化Bundle】。
zip包的下载时间是极大低于碎文件的下载时间的,这个时间差也就是启动加速的时间。
游戏内加速
对于游戏资源较大,或者说有众多子游戏的项目,加载游戏Bundle也可以加速。
通过调用window.installBundle来下载并缓存游戏Bundle,通过实现window.onBundleInstallProgress
来捕获下载和缓存进度,进度达到1时调用AssetManager的loadBundle方法,游戏资源就全部从本地缓存加载了。
时间有限,先讲如何使用
下载安装
建议安装Bundle Zipper到项目中,因为插件会生成项目打包的配置文件,在项目文件夹中方便手动修改
同时需要替换插件目录下img文件夹下的应用图标
插件配置
菜单栏中Packages -> BundleZipper
配置项 | 配置说明 |
---|---|
PWA应用名称 | pwa应用的manifest文件需求字段,会在添加桌面快捷方式、桌面快捷方式应用名上体现 |
PWA应用简称 | 同上 |
发布路径 | 如果访问路径为https://xxx.com/web-mobile/,则填入/web-mobile/,必须以/开头和结尾 |
资源CDN | 用于想把资源单独放在cdn的情况,如填入https://xxx.com,则应该将构建生成的cdn.zip解压到https://xxx.com/发布路径/,不填的情况下编译不会生成cdn.zip |
初始化Bundle | 在加载首个场景之前,这些Bundle会自动下载并缓存,Bundle名以英文逗号隔开 |
注:因为sw的注册必须指定一个固定路径,所以【发布路径】必须提前指定。
点击确定后,插件目录下会生成一个以工程名为命名的配置文件(如果面板输入不方便,可以手动修改配置文件内容)
代码构建
选择构建web-mobile后,插件会自动压缩所有Bundle,并修改index.html,拷贝相关脚本和资源。
最终产物包括两个:web.zip和cdn.zip(只有填写了资源CDN才会生成cdn.zip)
TODO: 目前发布包中包含了源文件和压缩文件,目的是为了使加载速度最大化,同时使用本地缓存和远程资源,下个版本会添加一个选项以支持全部从缓存的压缩Bundle中加载。
发布网站
假设插件配置的【发布路径】为【/web-mobile/】
则应该将web.zip解压到https://你的域名/web-mobile/访问目录下,即确保https://你的域名/web-mobile/下面是index.html等发布文件
发布资源(资源和网站分离的情况)
针对资源与网站分离的需求,可以配置【资源CDN】
将cdn.zip解压到【资源CDN/web-mobile/】下面即可
使用效果查看
发布之后,调试网页,在CacheStorage里面可以看到初始化缓存的Bundle。
如果想验证一下,可以将所有Bundle全部缓存,然后断网,这时候游戏资源都可以正常加载。
进阶使用(游戏中进行缓存控制)
// 安装缓存
window.installBundle(bundleName)
// 安装进度回调
window.onBundleInstallProgress: (bundleName: string, progress: number) => void
因为zip文件使用fetch拉取,因此progress只有两个数值:
0.5代表下载完成,即可调用loadBundle方法下载Bundle,此时加载速度最大化;
1代表全部缓存完成,此时loadBundle会全部走本地CacheStorage缓存
// 清理Bundle过期版本(正常用不到,在installBundle后会自动调用cleanBundle)
window.cleanBundle(bundleName)
// 清理所有Bundle缓存(客户端资源万一混乱时的最终解决方案,全部删除即可)
window.cleanAllBundles()