前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >针对 iOS 14 Web 端性能问题的解决方案

针对 iOS 14 Web 端性能问题的解决方案

作者头像
一枚小工
发布2020-10-30 14:38:28
9000
发布2020-10-30 14:38:28
举报
文章被收录于专栏:Cocos Creator开发Cocos Creator开发

在今天这个快乐周五的早上,我们一到公司就收到了一些 CP 的紧急反馈,在 iOS 14 上,H5 游戏的性能下降,线上项目受到严重影响。

经过验证,此问题波及 iOS 14 上的所有浏览器、WebView 运行环境,小游戏和原生游戏不受影响。引擎组立即着手调试,经过一天的排查,发现这个问题的症结在 vb 和 ib 的共享上。

为优化性能,Creator 多个 drawcall 之间会共享同一份 vb 和 ib,每个 drawcall 使用一个偏移值在共享 vb 和 ib 中找到本次渲染的数据,但是经过我们验证后发现,共享 vb 和 ib 会导致在 iOS 14 上性能下降非常严重。

所以修复此问题的关键就是,在提交 drawcall 之后,切换 vb 和 ib。经过修改,问题就能得到完全解决。

解决方案:

> 2.2 版本:

在项目脚本最外层加入如下代码,直接覆盖 cc.MeshBuffer 中的方法即可。

代码语言:javascript
复制
const isIOS14Device = cc.sys.os === cc.sys.OS_IOS && cc.sys.isBrowser && cc.sys.isMobile && /iPhone OS 14/.test(window.navigator.userAgent);
if (isIOS14Device) {
    cc.MeshBuffer.prototype.checkAndSwitchBuffer = function (vertexCount) {
        if (this.vertexOffset + vertexCount > 65535) {
            this.uploadData();
            this._batcher._flush();
        }
    };
    cc.MeshBuffer.prototype.forwardIndiceStartToOffset = function () {
        this.uploadData();
        this.switchBuffer();
    };
}

也可以自定义引擎,手动合并此PR:https://github.com/cocos-creator/engine/pull/7415 。

2.1.x 版本

原理和 2.2 一样,首先在项目脚本最外层加入如下代码,直接覆盖 cc.MeshBuffer 中的方法。

代码语言:javascript
复制
const isIOS14Device = cc.sys.os === cc.sys.OS_IOS && cc.sys.isBrowser && cc.sys.isMobile && /iPhone OS 14/.test(window.navigator.userAgent);
if (isIOS14Device) {
    cc.MeshBuffer.prototype.checkAndSwitchBuffer = function (vertexCount) {
        if (this.vertexOffset + vertexCount > 65535) {
            this.uploadData();
            this._batcher._flush();
        }
    };    
}

但 2.1 中没有实现 forwardIndiceStartToOffset,所以你还需要自定义引擎并找到 model-batcher.js,将 _flush 方法中的最后三行改为:

代码语言:javascript
复制
const isIOS14Device = cc.sys.os === cc.sys.OS_IOS && cc.sys.isBrowser && cc.sys.isMobile && /iPhone OS 14/.test(window.navigator.userAgent);

_flush () {
    let material = this.material,
        buffer = this._buffer,
        indiceStart = buffer.indiceStart,
        indiceOffset = buffer.indiceOffset,
        indiceCount = indiceOffset - indiceStart;
    if (!this.walking || !material || indiceCount <= 0) {
        return;
    }

    let effect = material.effect;
    if (!effect) return;

    // Generate ia
    let ia = this._iaPool.add();
    ia._vertexBuffer = buffer._vb;
    ia._indexBuffer = buffer._ib;
    ia._start = indiceStart;
    ia._count = indiceCount;

    // Generate model
    let model = this._modelPool.add();
    this._batchedModels.push(model);
    model.sortKey = this._sortKey++;
    model._cullingMask = this.cullingMask;
    model.setNode(this.node);
    model.setEffect(effect, this.customProperties);
    model.setInputAssembler(ia);
      
    this._renderScene.addModel(model);

    if (isIOS14Device) {
        buffer.uploadData();
        buffer.switchBuffer();
    }
    else {
        buffer.byteStart = buffer.byteOffset;
        buffer.indiceStart = buffer.indiceOffset;
        buffer.vertexStart = buffer.vertexOffset;
    }
},

2.0.x 版本

自定义引擎,并用此文件 https://forum.cocos.org/uploads/default/original/3X/2/6/2699adeb70a987f69ea2d72a5c5c953279c235dd.zip 覆盖引擎中的 mesh-buffer.js,然后再使用和 2.1.x 版本相同的改动方式修改。

注意:自定义引擎后需要重新编译引擎才能生效。建议合并后,使用不同手机进行全面测试。

诚挚道歉

对于本次意外给各位开发者朋友带来的困扰,我们感到非常抱歉。

性能是 Cocos 永远不变的追求,我们会持续关注这个问题,做好后续预案。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一枚小工 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解决方案:
  • > 2.2 版本:
  • 诚挚道歉
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档