查看原文
其他

微信小游戏首包超出 4M 之后

异名君 COCOS 2022-06-10

微信小游戏平台上对首包的的限制是 4M,超出限制之后可以采取什么样的措施呢?异名做了一下盘算,大概可以有以下操作——

挤牙膏式瘦身


如果我们能够在各种常规的瘦身手段下就可以把超出的容量压缩回到 4M 以内,那当然是最棒的。这一块能做的无非就是引擎的瘦身和资源的瘦身,而资源无外乎是图片、音频、字体等。

    引擎瘦身

首先是引擎代码本身,在开发阶段我们的引擎默认是所有模块都包含进去的,但是在打包阶段,有一些无用的代码模块我们就可以在项目-项目设置-模块设置中剔除掉。比如一个普通的 2D 游戏,可能就没有使用到 3D 模块、物理模块、EditBox 等等,我们最好根据实际的项目需要勾选自己需要打包的模块。根据异名自己的经验,大部分情况下做了引擎瘦身和没做引擎瘦身的前后对比,瘦身之后可能至少会帮你省掉你几百 k 的大小。

其中有些功能模块,它的名字不是很直观,你可能不知道自己有没有用到,那就不要勾选。

经常会有新手遇到,为什么打包前,在预览模式下项目跑得好好的,但是打包之后项目功能就不正常了?出现这种情况其实很大概率就是你的模块漏勾了,回去校对一下重新打包就可以了。

    资源瘦身

资源无外乎是图片、音频、字体。如果是寻常的 web 项目,我们其实有常用的几个构建工具,像 gulp/grunt/webpack 等等,引用相关的压缩库,然后执行构建命令即可。

但是异名还是觉得没有引入构建工具的必要,因为代码压缩和名字 hash 引擎已经自身支持了,那音频和字体其实在我们使用之前,只要使用工具一次性压缩就可以了。而图片则因为数量太多以及会涉及到自动合图,所以需要在构建之后重新压缩一遍,但是我个人会比较倾向于依赖引擎自身提供的插件机制,毕竟使用了构建工具之后起码还得去 npm install 一下,还要去设置每个包自身的一些配置,然后项目 build 完之后还得去敲个命令,整个一套走下来,其实效率还是不够高。

而且针对图片压缩,社区内其实已经有能够开箱即用的相关插件,像 pngquant 我就用挺顺手的,而且在它的基础上也可以添加一些自己的发布流程进去,比如我就把文件夹改名放到里面,后续的项目直接拷贝过去使用就可以了。


音频这块我建议还是使用第三方的工具吧,我自己习惯使用 ffmpeg。

如果有用到其他字体的话,一款普通的中文字体大几十 M,但是我们使用字可能就是那么几个,所以字体提取也很有必要。其实社区内有收费的插件,但是目前中文字体提取库无非就是 Fontmin 或者字蛛,它们都可以通过终端命令或者客户端和 web 端去提取所需的字体。


资源远程加载


既然本地放不下了,那就把资源放在远端吧。

这块引擎的支持也很好,在打包构建的时候填写远程服务器地址,然后把打包后的 res 目录存放到服务器下,再删除本地的 res 文件夹就可以了。

运行的时候如果在本地没有这个资源就会去远端获取。但是呢,异名在权衡之后,并不会选择这个方案,首先第一个问题是资源在远端,加载会有网络延迟,这个时候场景是黑屏的,解决这个问题可以做一个简单的初始场景,初始场景的资源还是保留在本地,然后在初始场景预加载真实的游戏场景,等到加载完了之后跳转过去。

cc.director.preloadScene("Game", (completedCount, totalCount) => {// 在这里处理加载进度console.log(completedCount, totalCount);}, (error, asset) => {if (error) { cc.error(error);return; } cc.director.loadScene("Game")});

但是这里的骚操作就是你得在 res 文件夹里面挑选你的首屏资源。

面对一堆嵌套的文件和无规则的文件夹名称,那是多大的效率浪费呀,为了提高效率,异名看到社区内看到有人专门写个 Python 脚本(怎么感觉发力点选错了呢...),当把资源挑选完毕之后,还得把 cdn 上的 res 文件夹删掉,然后重传,那这个发版过程也未免太过于太琐碎了。

还有就是网络请求多了,万一遇到个网络不好报个 timeout 呀,或者资源更新但是你的 cdn 节点还没同步过来,然后报个 notFound 什么的,那也得做个异常处理是吧。 


除了上面说的,异名觉得最关键的还有费用问题,流量都是钱啊,明明微信总包大小有 8M,有多少小游戏经过合理的瘦身之后总包大小还能超过 8M 呢?

而且微信针对网络资源还有一套自己的缓存管理机制,有限的缓存空间满了之后,还要自己去做缓存清理,而且很重要的是微信会在小游戏退出之后自动清理所有临时文件,所以下次再次运行小游戏时,这些资源又会再度下载,然后一直循环往复此过程,几乎每次打开都会重新去拉取,cdn 的流量就这么被挥霍掉了。


当然每种手段都有每种手段的应用场景,异名在社区内还看到有同学利用微信的文件系统去拉取 zip 资源,然后通过 unzip 命令去解压的,如果你的游戏资源确实很多很大,那也难以避免的需要使用远程资源,具体场景还是得合理分析才行。

    分包

引擎对分包的支持真的非常好啦,对应的文件夹中打个勾就行了。

异名的做法其实是多加了一个 loading 场景,然后把主场景的资源都放在分包里面,在 loading 场景中通过 loadSubpackage 监听下载分包,下载完成后再跳转主场景就可以了。

和资源远程加载相比,整个配置步骤清晰明了,发版过程简单流畅,而且省了你的 cdn 流量,同时微信自身还会对代码包进行主动缓存,一次下载之后就会缓存下来方便下次使用。异名把两者一对比,觉得分包那是真的香啊~

cc.loader.downloader.loadSubpackage("Game", progressInfo => {// 在这里处理加载进度console.log(progressInfo.progress);}, error => {if (error) { cc.error(error);return; } cc.director.loadScene("Game")});

有几个小点还是需要注意一下:

  • 老版本兼容:由微信后台编译来处理旧版本客户端的兼容,后台会编译两份代码包,一份是分包后代码,另外一份是整包的兼容代码。对于老客户端,会去下载整包代码启动。
  • 2.1.0  以下版本基础库不存在 wx.loadSubpackage 方法,需要通过 require 来加载(可以在后台屏蔽以下的用户)。
  • 微信 6.6.7 以下客户端开发版/体验版因历史兼容问题无法打开分包小游戏,正式包可以。

 总结


说这么多,总结下来就是,如果你的代码包超过 4M,请先进行各种压缩。

如果确实已经是极限压缩了,那使用分包会比远程资源相对来说更加成本更低也更合理。

另外异名并不建议子域使用 Cocos 构建,因为确实构建之后又多了一个引擎,首包确实很难控制下来,好的选择是使用 canvas 的 api 去绘制或者使用一个简单的模板渲染引擎,当然,这就是另外一个话题了 。


 

以上就是今天的教程详解
再次感谢异名的倾情分享
如果您在使用 Cocos Creator 2D/3D 时
 get 了独到的开发心得、见解或是方法
欢迎随时向我们投稿
帮助更多开发者们解决技术问题
让游戏开发更简单~

期待您与我们联系~


【更多精彩】

如何在80天内快速拓展海外游戏市场?
Creator H5游戏开发教程 PDF 免费下载
微信公众号如何设置星标??
如何在 Cocos Creator 中嵌套 Prefab?
Cocos 插件开发者的福音来了……
零基础入门 Cocos Creator 3D
ironSource Abby:畅谈出海买量变现方法论
为武汉游戏人点赞!3D《巅峰漂移》技术分享
《江湖医馆》:用 Cocos Creator 开发原生游戏


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存