9月15日,无惧17级台风“山竹”,320名开发者齐聚广州贝塔空间共同探讨“怎样作一款赚钱的小游戏”。针对众多开发者关心的重度H5游戏性能优化技巧,咱们整理了现场速记分享给你们,详见下文:浏览器
王泽:各位开发者下午好!我叫王泽,是白鹭引擎的首席架构师。缓存
今天给你们分享的题目是《重度H5游戏性能优化技巧》。之因此决定用这个题目,是由于我最近几周在广深一带拜访了不少使用白鹭引擎的开发者,发现特别是在广州一带,大部分开发者都在作重度H5游戏。在几周的拜访过程当中,我协助许多广州的游戏开发团队进行游戏性能优化,并在在这个过程当中发现不少开发者遇到的问题是很是类似的,因而我借此次开发者沙龙的机会,把这些优化技巧整理出来与广大开发者分享。
这些技巧都是我在实际项目中获得验证过的优化技巧,而且都是投入产出比很高的优化项,建议作重度H5游戏的开发者重点针对您们的游戏进行这些优化。性能优化
在开讲以前,我首先为你们回顾一下白鹭引擎的历史上几个比较重要的版本。2014年3月白鹭引擎发布了0.9版本,并产生了《围住神经猫》这一爆款。紧接着一气呵成发布了1.0版本引入了完整的GUI,这使得开发者能够开始作具有大量复杂 UI界面的游戏,《愚公移山》就是这样的一款产品,他成功的在 2014年末就取得了每个月180万流水的成绩。微信
接着在 2014年11月发布了 2.0版本,重点包含了白鹭引擎的工做流工具集,特别是 UI 编辑器与动画编辑器,这对游戏开发效率带来了重大提高,所以在 2014年末,使用了白鹭引擎 2.0 版本的《传奇世界H5》 成为了第一款月流水超过千万的 H5 游戏。2016年1月,白鹭发布了3.0版本,这个版本引入了 WebGL 渲染器,大幅提高了游戏渲染效率,这个版本获得了开发者的广泛欢迎,《决战沙城》更是用这个版本实现了 H5 游戏月流水三千万的成绩。网络
2016年末,白鹭引擎自研了一款名为《莽荒纪》的产品,并同步推出白鹭引擎4.0版本。这款游戏使用了大量的骨骼动画,对动画渲染性能和资源加载效率的要求很是高,得益于4.0版本针对这两点的优化,这款产品在绝大部分设备包括千元机上都有很是好的表现。2017年5月份,白鹭引擎发布了 5.0版本,市场上也出现了第一款月流水过亿的H5游戏——《传奇来了》。架构
紧接着,在微信发布小游戏后,第一时间发布了引擎5.1版本正式支持微信小游戏,《海盗来了》经过白鹭引擎的底层支持,仅用3天便将游戏从H5版本发布到微信小游戏平台,成为首款月流水过亿的微信小游戏。编辑器
回顾白鹭引擎的历史,咱们就会发现,随着软硬件的不断升级以及白鹭引擎每一个版本迭代的持续努力,不断的刷新着 H5游戏行业的新高度。但咱们并未躺在过去的功劳簿上,仍然在持续高效率的进行版本迭代。函数
白鹭引擎目前按照双周迭代的节奏,同时发布5.2稳定版与5.3特性版本,若是开发者想要开发商业化游戏,可用5.2稳定版原本作;若是你想使用一些新的特性,好比说3D以及一些2D的高级优化技巧,就可使用白鹭引擎最新的5.3版原本作。
白鹭引擎目前在H5游戏的市场占有率达到了70%。统计方法是:取样爱微游、疯狂游乐场以及QQ空间三个业内公认的头部渠道的Top30的游戏,逐一去看这些游戏采用了哪些游戏引擎。
除了H5游戏以外,白鹭引擎在微信小游戏上的市场占有率53%。这里有两种统计方法:第一种统计方法是把全部能统计到的微信小游戏都统计起来,一个一个抓包看是什么引擎作的。工具
经过这种方式,统计到的白鹭引擎的市场占有率高达80%,可是我认为这是有失偏颇的数据,由于能统计到的小游戏有很大一部分是由于与白鹭官方人士有微信好友关系,而这部分好友几乎都在使用白鹭引擎开发微信小游戏,因此我认为这种统计方式是并不许确的。因而咱们采用了另外一种更为公平的统计方法,经过相对权威的阿拉丁统计数据,把阿拉丁榜单的Top50拉出来,得出白鹭引擎市场占有率为53%。
据不彻底统计,这五年中,白鹭引擎累计运转的H5游戏和微信小游戏的流水数据约为200亿。很是感谢你们对白鹭引擎的支持。今天能有这个成绩并非彻底是依靠白鹭本身作的,引擎技术并不能解决全部的问题,最大的外因是依靠各位一块儿努力的结果,特别是各位游戏开发者,浏览器底层技术提供方、渠道方、以及不少支持伙伴的帮助。性能
除了外因的帮助以外,白鹭自身也帮助开发者作了不少事情,我我的是Flash页游研发出身,白鹭引擎团队的大部分研发也都是游戏行业出身,因此白鹭的研发团队更了解也被称为“手机页游”的H5游戏开发者的痛点需求,而且这五年为各地的H5游戏开发者提供了总计1400天的驻场支持,飞到各个城市,包括广州、深圳、上海、厦门、福州、成都、武汉、南京、西安,固然还有北京。我平均基本上有三分之一的时间是不在公司里的,都在为各地的开发者解决各类各样的问题。经过这些比较务实、接地气的方式,保证白鹭引擎能够运行在尽量多的设备上,并提高在低端机上的游戏体验。
今天广州开发者沙龙的主题是“怎样作一款赚钱的小游戏”。我认为解决技术上的短板决定了游戏是否能赚钱的下限。针对游戏运营的几个关键数据,游戏的运行性能主要影响玩家的在线时长,游戏加载性能主要影响玩家的前期留存。我今天重点介绍如何提高游戏的运行性能。
我见过的大部分寻求技术帮助的 CP 都会说起游戏性能须要提高。可是我认为性能糟糕是一个技术术语,它在产品上通常有以下四种体现方式:
一、帧频很低。
二、设备发热。
三、不按期卡顿。
虽然看起来这些问题都是性能问题,可是产生这些问题背后的缘由则是彻底不同的。
在解决问题以前,须要将这些问题首先输出一个可量化的数据指标。
帧频很低能够被量化为:在特定设备上的帧频是XX帧,其中 JavaScript 逻辑开销 XX毫秒,渲染开销YY毫秒,这些数据在白鹭引擎的性能面板中都有体现。
设备发热看似是很难量化的,并非全部操做系统都提供了设备温度的 API。所以咱们向开发者推荐另外一种方法做为量化方式,首先将设备充满电,而后统计游戏在 XX分钟后的剩余电量。因为耗电量和发热基本成正比,因此解决耗电问题,发热问题就也能同步获得解决。
至于不按期卡顿。必定要记录卡顿是否存在规律。好比是播放动画的瞬间?打开UI面板的瞬间?或者是毫无规律?
上述问题量化以后,接下来再来逐一地尝试解决这些问题。
帧频低和发热主要有以下四个缘由:
一、渲染内容过多。
二、渲染方式不当。
三、计算开销过大。
四、 大量建立对象。
这四点又分属两个类别,分别是 JavaScript逻辑开销和引擎渲染开销。关于渲染内容和渲染方式不当最终是能够在引擎渲染层这个环节想办法解决的。而计算开销过大和大量建立对象都是在用户逻辑的JavaScript层去解决的。这两块的解决方式是彻底不同的,对渲染来讲,你须要去尝试理解WebGL底层的渲染原理是什么,而对于JavaScript,你须要了解JavaScript底层的一些原理。
首先聊聊引擎渲染层面的东西:
一、渲染内容过多。在屏幕以外的内容,能够设置隐藏,不要执行渲染。这就提到一个颇有意思的问题了,看似很简单优化方法为何不在白鹭引擎内部实现呢?其实这涉及到白鹭引擎的一个核心设计理念:不要替开发者去作“自做聪明”的优化。这样才能保证优秀开发者作出更好的游戏。除了屏幕外的内容不进行渲染以外,游戏广泛有不少UI弹窗,当你打开弹窗的时候,强烈建议你把游戏背景隐藏,这一样能够节省大量的渲染开销。
二、渲染方式不当。来看看底层原理:
白鹭引擎2D是如何渲染游戏的多张纹理的? 在白鹭引擎里,2D是一次性提交全部的数据,而后设置渲染模式,执行渲染批次,再设计渲染模式,再执行渲染批次。若是你能保证渲染模式这个东西是没有发生变化的,就能够一次尽量多地渲染,在这种状况下就能够作一次的渲染批次,这个优化听起来很简单,我说说在实际游戏里的典型案例。
这张图是我昨晚本身画的示例图。作游戏时常常会遇到这样的场景,就是有不少人、不少怪,每一个人都包含了影子、模型动画、血条三个部分。最简单的渲染方式是,将一我的设置成一个 DisplayObjectContainer,这个对象有三个子对象:一我的、一个影子和一个血条,这样每一个人的渲染次数就是3,进而8我的的渲染次数就是24。优化后是10,如何作这个优化?方法很是简单,就是你把全部的影子放在一个Container上,把人放在一个Container上,再把血条放在一个Container上。
因为全部影子的纹理都是同样的,因此引擎底层会自动开启批次合并,渲染次数是是1,而后渲染8我的,这8我的的纹理通常都是不同的,因此就是8,上面就是血条的纹理也是同样的因此也是1。把这三者加起来,最终的优化结果就是从 24下降到10。
第二个示例。这是你们作的重度游戏的典型UI,DrawCall是30,这种游戏能够作不少优化,就是把全部的图片、文字合成一张纹理集。这个全作完以后,渲染批次就从30变成2,之因此不是1而是2,是由于右上角的lv888确定是个动态文本,没法参与批次合并。
因此这就是一个简单的例子,但愿你们之后作UI 时能够尝试着去把全部的动态文本都尽量放在最上层,把图片都放在下层,并将这些图片合并成纹理集。特别是在游戏的 ListItemRenderer 之中,通常游戏中的一个 List 至少会显示 5个 ListItemRenderer,若是你能将 ItemRenderer的DrawCall下降5,那总体的 DrawCall就能下降 25,因此针对ListItemRenderer的优化是投入产出比很是高的,强烈推荐各位开发者重点优化这里。
三、计算开销过大。对骨骼动画使用缓存,优化骨骼开销;避免大量的数学计算与浮点数计算;逻辑帧与渲染帧分离。这个提高是比较明显的,由于不少游戏都是作30帧的,可是如今有些是60帧,因此要做一些逻辑帧和渲染帧的分离,逻辑上能够是15帧,而后渲染上作60帧,那么逻辑的开销就能够少不少。
四、还有一个是很是重要的你们可能不太注意的,就是大量建立对象。JavaScript虚拟机有一个特色,就是对象建立的开销远远大于对象计算的开销,而且对象建立会致使垃圾回收,而垃圾回收会致使游戏不按期卡顿,因此有一个很重要的原则就是不要在你的主循环里建立任何对象,强烈建议游戏中的人物、怪物、技能特效通通作成对象池,这样能够大幅下降游戏的不按期卡顿现象的出现。分享一个经常使用的测试函数。
来看这个函数的原理。它就是显示了每一秒钟去拿一个hashCount跟上一个hashCount做对比,这个hashCount是由白鹭引擎内部 API,用于统计引擎对象的建立数量。若是你的游戏静止放置不动,那么理论上hashCount diff的结果应该是0,实际上要尽量控制在120如下,我给你们分享一个数据,我见过的最赚钱的那一批游戏的 hashCount diff 都控制在120如下的。
若是这个数字超标,应该如何去解决呢?只须要在引擎的 HashObject 的构造函数这里添加一个断点,在运行时去检查调用堆栈就能够了。
我协助优化过一款产品,它的hashCount diff数字高达4000,每秒建立4000个对象,我调试他的代码后发现,其实只是一个很小的问题致使了这个结果,花了15分钟修复以后,游戏的发热、卡顿等问题都获得了大幅的缓解。
接下来我跟你们介绍一下白鹭的3D引擎的核心功能,以及内部优化技巧,也给你们作重度游戏时以一些启发。
Egret3D内部的全部资源都采用了GLTF文件格式。这是一种对OpenGL ES、WebGL很是友好的3D内容格式标准。面向实时渲染,尽可能提供可直接传输给图形API的数据格式,而再也不须要反序列化。
刚刚我提到了尽可能提供可直接传输给图形API的数据格式,在 Egret3D内测版本中,在3D引擎加载一个模型文件,须要首先加载了模型文件,而后解析模型文件,这就像配置文件同样。第三步要生成WebGL所须要的数据格式,最后把它提交到GPU。而在正式版本的流程变成了加载新的 GLTF文件,进而因为GLTF的文件格式和GPU想要的文件格式是几乎同样的,因此不须要解析也不须要生成,直接把它做一个简单的ArraryBuffer切割,而后提交到 GPU就能够了。
经过这个优化达到什么样的效果?模型解析速度提高170%,内存占用下降1倍,加载速度提高30%,全部这些优化的底层的本质缘由是因为底层采用了GLTF的模型文件的标准范式。这就至关因而白鹭引擎3D版本的比较常见的引擎优化。
《泡泡学园OL》是白鹭自研团队打造的一款标杆品质的3D微信小游戏。在这款游戏制做过程当中,不断挑战 Egret3D 与微信小游戏的性能极限极限,具体技术指标包括: 100,000 Vertex , Lightmap贴图、GPU骨骼动画,GPU粒子动画,碰撞引擎,帧同步网络通信,基于行为树的AI 等。
这款游戏前期开发过程当中使用了 Unity3D 编辑场景,而后经过白鹭引擎的 Unity3D导出插件发布到 Egret3D 中。目前已经使用白鹭引擎正在研发的 3D 编辑器进行后续开发和维护。
目前白鹭科技已经发布了 Egret3D的1.1版本,即将在9月底发布1.2版本,这个版本重点针对开发者的开发效率进行优化,首先是推出一款可视化的调试工具 Egret Inspector 3D ,其次就是将3D编辑器提供给更多开发者进行试用并收集反馈,若是您已经使用 Egret3D 立项并进入项目开发阶段,能够优先试用3D编辑器。以上就是我为你们分享的所有内容。谢谢你们!