cocos-awesome/doc/Essays/4M_limit.md
2020-04-14 23:57:16 +08:00

53 lines
7.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

微信小游戏平台上对首包的的限制是4M超出限制之后可以采取什么样的措施呢异名做了一下盘算大概可以有以下操作
# 挤牙膏式瘦身
如果我们能够在各种常规的瘦身手段下就可以把超出的容量压缩回到4M以内那当然是最棒的。这一块能做的无非就是引擎的瘦身和资源的瘦身而资源无外乎是图片音频字体等。
## 引擎瘦身
首先是引擎代码本身,在开发阶段我们的引擎默认是所有模块都包含进去的,但是在打包阶段,有一些无用的代码模块我们就可以在`项目-项目设置-模块设置`中剔除掉比如一个普通的2D游戏可能就没有使用到3D模块、物理模块、`EditBox`等等我们最好根据实际的项目的需要勾选自己需要打包的模块根据异名自己的经验大部分情况下做了引擎瘦身和没做引擎瘦身的前后做对比瘦身之后可能至少会帮你省掉你几百k的大小。其中有些功能模块它的名字不是很直观你可能不知道自己有没有用到那就不要勾选。经常会有新手遇到为什么打包前在预览模式下项目跑得好好的但是打包之后项目功能就不正常了出现这种情况其实很大概率就是你的模块漏勾了回去校对一下重新打包就可以了。
## 资源瘦身
资源无外乎是图片音频字体。如果是寻常的web项目我们其实有很常用的几个构建工具像`gulp/grunt/webpack`等等引用相关的压缩库然后执行构建命令就可以了但是我个人觉得还是没有这种必要引入构建工具因为代码压缩和名字hash引擎已经自身支持了那音频和字体其实在我们使用之前只要使用工具一次性压缩就可以了而图片则因为数量太多以及会涉及到自动合图所以需要在构建之后重新压缩一遍但是我个人会比较倾向于依赖引擎自身提供的插件机制毕竟使用了构建工具之后起码还得去`npm install`一下还要去设置每个包自身的一些配置然后项目build完之后还得去敲个命令整个一套走下来其实效率还是不够而且针对图片压缩社区内其实已经有能够直接就开箱即用的相关插件像`pngquant`我就用挺顺手的,而且在它的基础上也可以添加一些自己的发布流程进去,比如我就把文件夹改名放到里面,后续的项目直接拷贝过去使用就可以了。
![pngquant_customizing](https://mmbiz.qpic.cn/mmbiz_png/7ENgv1sV63dlnib2eGVQ5Jr9eP3bfg7jkiaDfGkYIVhPkwrTEQXBOFevkOgicic21PB4mAvu7ZEvNUs2omRYAfibnAg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)
音频这块我建议还是使用第三方的工具吧,我自己习惯使用`ffmpeg`。如果有用到其他字体的话一款普通的中文字体大大几十M但是我们使用字可能就是那么几个所以字体提取也很有必要其实社区内有收费的插件但是目前中文字体提取库无非就是`Fontmin`或者字蛛它们都可以可以通过终端命令或者客户端和web端去提取所需的字体异名以前也写过一款小工具大家需要的话可以去下载来用地址放在原文链接。
![fontmin_tool](https://mmbiz.qpic.cn/mmbiz_gif/7ENgv1sV63dlnib2eGVQ5Jr9eP3bfg7jkqYzeUy70E4fvPQhNZBF5iaJvCLrMZjZtiau4Ziaz3Ogl1KVYvblB0FfxA/640?wx_fmt=gif&tp=webp&wxfrom=5&wx_lazy=1)
# 资源远程加载
既然本地放不下了那就把资源放在远端吧。这块引擎的支持也很好在打包构建的时候填写远程服务器地址然后把打包后的res目录存放到服务器下再删除本地的res文件夹就可以了运行的时候如果在本地没有这个资源就会去远端获取。但是呢异名在权衡之后并不会选择这个方案首先第一个问题是资源在远端加载会有网络延迟这个时候场景是黑屏的解决这个问题可以做一个简单的初始场景初始场景的资源还是保留在本地然后在初始场景预加载真实的游戏场景等到加载完了之后跳转过去
```js
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`呀什么的,那也得做个异常处理是吧。
![resource_error](http://cdn.blog.ifengzp.com/cocos-awesome/4M_limit/4M_1.png)
除了上面说的异名觉得最关键的还有费用问题带宽都是钱啊明明微信总包大小有8M有多少小游戏经过合理的瘦身之后总包大小还能超过8M呢而且微信针对网络资源的还有一套自己的缓存管理机制几乎每次打开都会重新去拉取cdn的流量就这么被挥霍掉了。
![cdn_waste](http://cdn.blog.ifengzp.com/cocos-awesome/4M_limit/4M_2.png)
当然每种手段都有每种手段的应用场景异名在社区内还看到有同学利用微信的文件系统api去拉取zip资源然后通过unzip命令去解压的如果你的游戏资源确实很多很大那也难以避免的需要使用远程资源具体场景还是得合理分析才行。
### 分包
引擎对分包的支持真的非常好啦对应的文件夹中打个勾就行了。异名的做法其实是多加了一个loading场景然后把主场景的资源都放在分包里面在loading场景中通过`loadSubpackage`监听下载分包下载完成后再跳转主场景就可以了。和资源远程加载相比整个配置步骤清晰明了发版过程简单流畅而且省了你的cdn流量同时微信自身还会对代码包进行主动缓存一次下载之后就会缓存下来方便下次使用。异名把两者一对比觉得是分包那是真的香啊~
有几个小点还是需要注意一下:
- 老版本兼容:由微信后台编译来处理旧版本客户端的兼容,后台会编译两份代码包,一份是分包后代码,另外一份是整包的兼容代码。对于老客户端,会去下载整包代码启动
- 2.1.0 以下版本基础库不存在`wx.loadSubpackage`方法需要通过require来加载可以在后台屏蔽以下的用户
- 微信 6.6.7 以下客户端开发版/体验版因历史兼容问题无法打开分包小游戏,正式包可以
## 总结
说这么多总结下来就是如果你的代码包超过4M请先进行各种压缩如果确实已经是极限压缩了那使用分包会比远程资源相对来说成本更低也更合理。另外异名并不建议子域使用cocos构建因为构建之后又多了一份引擎代码首包确实很难控制下来好的选择是使用canvas的api去绘制或者使用一个简单的模板渲染引擎当然这就是另外一个话题了