独角兽企业重金招聘Python工程师标准>>>
目前在做一个放置类的微信小游戏,时间过去了一个多月,大的功能已经很少了,是时候来一波优化了。策划那边还是在浏览器上查看游戏,反映了几个问题,主要是操作延迟。这个分为几个方面:
网络延迟:包括资源服务器延迟,小程序的资源大部分都是放在资源服务器上的,加载这些资源会出现延迟;另外还有游戏逻辑服务器的延迟IO延迟:从手机存储读取文件是很慢的,尤其是一堆文件的时候渲染延迟:组件太多、太深,渲染压力大性能问题:复杂的逻辑、计算密集型的任务导致主循环被持续占用,反映出来就是ui响应慢
路要一步一步走,饭要一口一口吃。我们今天就先来聊聊如何解决网络延迟的问题。
预下载所需资源
首先我们要看下,creator在小游戏环境中是如何下载资源的。creator提供了一个wxDownloader对象用来处理远程资源的加载,步骤如下:
1、检查资源是否在小游戏包内2、不存在则查询本地缓存资源3、如果没有缓存就从远程服务器下载4、下载后保存到小游戏应用缓存内供再次访问时使用 具体请看官方文档 官方的实现是将wxDownloader作为加载资源的第一个管道,依旧是按需下载。但是,这样会导致首次访问慢的问题。现在,我们的工作就是将按需下载替换成提前预下载。这里需要在我们的loading页下载所有需要的资源,下载完毕之后再进入游戏。这里有几个问题:1、如何知道需要预下载的资源 这里我们需要再发布远程资源的时候附带生成一个manifest文件,用于记录该版本所有需要预加载的资源。2、并发地执行下载,但需要注意的是,同时超过10个网络请求会报错,所以需要限制你的并发数量 具体代码很简单,可以参照官方的wxDownloader的实现。并发那里我自己用promise封装了一下,将所有的处理步骤作流式处理,按照需要建立多个管道。大概是这样的:
preload(items){if(!items){this._onCompleted();}// 最后一条不读this._totalCount = items.length - 1;this._items = items;const pipeCount = Math.max(1, Math.min(this._totalCount, this.maxPipe));for(let i = 0; i < pipeCount; i++){this._nextHandle();}},_nextHandle(){const path = 'res' + this._items[this._processCount];// ttf不读if (path.substr(-3, 3) === 'ttf') {this._addProgress();} else {this.handle(path);}},_onCompleted(){if(this._completedFlag){return;}this._completedFlag = true;console.log('completed state:', this._savedCount, this._processCount, this._totalCount);console.log('fail to process:', this._failPathes);if(typeof this._onCompleteCallback === 'function'){this._onCompleteCallback();}},_addProgress(){this._savedCount++;this._process();if(this._processCount >= this._totalCount){this._onCompleted();}},_addFail(path){this._failPathes.push(path);this._process();if (this._processCount >= this._totalCount) {this._onCompleted();}},_process(){if (this._processCount >= this._totalCount) {return;}console.log('state:', this._savedCount, this._processCount, this._totalCount);this.stateLabel.string = this._processCount + '/' + this._totalCount;this._processCount++;this._nextHandle();},handle(path){console.log('handle:', path);this.existPromise(path).then(()=>{console.log(`${path} exist!!`);}, ()=>{return this.downloadFilePromise(path);}).then(()=>{this._addProgress();}).catch(()=>{this._addFail();})},
转圈动画
是的,加一个转圈动画,或者延迟加一个转圈动画对玩家的感受真的不一样。不要笑!!之前做过一个手游项目,由于服务器的问题,导致玩家经常会感知到转圈,客服收到无数投诉,大家拼命催促后端小哥优化性能。这时候我灵机一动,把特定rpc的转圈动画出现延迟了0.5秒,发出热更,结果玩家纷纷发帖表示网络好了(我当时就笑趴在了桌子上),直到几个特定rpc的性能问题被修复都再没有玩家向我们投诉这个问题
TO BE CONTINUE
如果觉得《cocos creator微信小游戏优化之路(一)》对你有帮助,请点赞、收藏,并留下你的观点哦!