这是个人关于微信小游戏系列文章的第三篇,在这系列文章里会描述 ——

  • 如何把一些 Canvas/WebGL Demo 移植到小游戏环境并支持双端运行;
  • 对小游戏在 Android 平台的运行时架构进行分析;
  • 通过对移植的 Canvas/WebGL Demo 在小游戏和 Chrome for Android 浏览器上做 Benchmarking,对 H5 游戏 vs 小游戏的渲染性能进行对比和分析;

测试说明

测试软件

  1. 微信 6.6.3
  2. Chrome for Android 64.0.3282.137

测试使用的 Demo 可以通过 GitHub 下载。

测试设备

小米 Note3,使用骁龙 660,算是这两年比较主流的中端芯片,虽然性能在高负荷场景下跟旗舰芯片如骁龙 835 还有一定距离,不过大部分场景下也已经够用。

测试环境

设备电量在 60% 以上,处于充足状态,并使用风扇进行辅助散热,避免因为电量不足或者过热导致设备锁核降频,从而引起测试数据的波动,无法获得可以对比的测试结果。

页面在 Chrome 上运行在全屏的 WebApp 模式下,如果没有额外说明,Canvas 的渲染分辨率使用设备的屏幕分辨率 1080p。

帧率获取

adb shell "dumpsys SurfaceFlinger --latency 'TARGET_WINDOW_NAME'"

使用上述命令可以获取目标窗口最近 127 帧的更新时间戳,然后用脚本计算出这 127 帧渲染过程中的平均帧率。

另外代码中也通过计算 JavaScript 中每帧调用的次数和时间间隔来计算帧率,然后通过控制台打印输出类似下面的信息,实际验证两者的结果基本一致。

WebGL Aqua framerate:1.55fps, program:44, draw call:118

本文的测试数据使用第一种方法

测试数据

WebGL Compute

模拟鸟群的运动,包含大量的物理运动计算,实际上是测试 JavaScript 的计算性能。

可以对 numBoids (guimark3.js)参数进行修改,改变鸟群的数量,鸟群数量越大,JavaScript 计算的耗时就越大。

运行环境 250 鸟群 500 鸟群
小游戏 58 ~ 59 21 ~ 22
Chrome 58 ~ 60 20 ~ 21

WebGL Aqua

绘制的场景有一定的复杂度,包含了约 30 个模型,使用了 44 个 Program,当参数设定为 500 条鱼时,需要调用 600 多个 Draw Call(不使用 Instance Rendering 的情况下)。

可以配置的参数如下:

  1. fishSetting 可以修改鱼的数量(aquarium-common.js);
  2. antialias 可以选择开启或者关闭抗锯齿(webgl.js);
  3. TRY_USE_WEBGL2 可以选择是否使用 Instance Rendering(wxhelper.js);
  4. 使用 GetCanvasSizeUseWindowRatio(720/600) 或者 GetWindowSizeInPx 选择不同的渲染分辨率(aquarium.js - setCanvasSize);
运行环境 100 条鱼 200 条鱼 500 条鱼 1000 条鱼 2000 条鱼
小游戏 52 ~ 53 52 ~ 53 58 ~ 59 58 ~ 59 37 ~ 38
Chrome (关闭抗锯齿) 60 60 60 58 ~ 60 39 ~ 40
Chrome (关闭抗锯齿, 720p) - - - - 60
Chrome (关闭抗锯齿, Instance) - - - - 52 ~ 54
Chrome (打开抗锯齿) 60 60 42 ~ 44 28 ~ 30 18 ~ 19
Chrome (打开抗锯齿, 720p) - - 60 51 ~ 53 31 ~ 32
Chrome (打开抗锯齿, 600p) - - - 60 42 ~ 43
Chrome (打开抗锯齿, Instance) - - 56 ~ 60 47 ~ 51 35 ~ 36
Chrome (打开抗锯齿, Instance, 720p) - - - - 58 ~ 60
  1. 小游戏不支持抗锯齿,无论设置 antialias 参数为 true 或者 false,结果都是 false,Chrome 默认是打开抗锯齿,需要显式关闭;
  2. 小游戏目前并不支持 WebGL2,WebGL2 新增的 API 并没有实现;
  3. 小游戏只能使用屏幕像素大小的渲染分辨率;
  4. 小游戏在 100 ~ 200 条鱼时帧率反而更低,反复验证过几次均是如此,怀疑踩到了什么坑,应该不是性能瓶颈;
  5. 小游戏最高帧率不会达到 60,最多就是 58 ~ 59,或许是 requestAnimationFrame 的实现有些问题;

Canvas Bitmap

类似雷电的小游戏,多个小位图的重复绘制,主要测试 Canvas.drawImage 的性能,跟微信开发工具自带的样例游戏类似。

可以对 enemiesCount(guimark3.js),改变敌机的数量,从而增加或者减少 drawImage 的调用次数。

运行环境 ~1000 drawImage ~2000 ~4000
小游戏 58 ~ 59 58 ~ 59 51 ~ 53
Chrome 60 60 30 ~ 31

性能分析

渲染流水线

在 Chrome 渲染流水线里面,Canvas 元素的更新跟其他 DOM 元素的内容更新一样,都需要走非合成器动画的渲染流水线。而非合成器动画渲染流水线过于复杂和冗长,比较小游戏简单和直接的渲染流水线,会有较多的 Overhead。

不过假设网页的运行条件跟小游戏一样,页面只有一个 Canvas 元素而不存在其他 DOM 元素,这些 Overhead 其实每个环节的耗时都很小,加上 Chrome 多线程高并发的流水线设计,实际上大部分开销都可以忽略不计,对整体性能的影响微乎其微。

WebGL Compute 的测试结果也验证了这一点,该 Demo 只有一个 Draw Call,所以我们基本可以忽略绘制部分的影响,JavaScript 计算的开销也可以认为是基本相同,在小游戏和 Chrome 的性能测试结果基本一致的情况下,我们可以推断出渲染流水线本身不会造成明显的性能差异。

关于 Chrome 非合成器动画的渲染流水线可以参考我的文章 - 浏览器渲染流水线解析与网页动画性能优化。

JavaScript Computing

我们把 JavaScript Computing 定义为除了 Native API(2D Canvas,WebGL,etc…)外的其它纯 JavaScript 代码运行的耗时。

小游戏和 Chrome 都使用 v8 虚拟机运行 JavaScript 代码,理论上 JavaScript 计算的性能不会存在较大差异,些微的差别可能来源自 v8 的版本差异,WebGL Compute 的测试结果也验证了这一点。

WebGL

Chrome 对比小游戏 WebGL 绘制的差别在于:

  1. 小游戏的 WebGL 调用会直接调用对应的 GL API,Chrome 使用了跨进程/线程的 CommandBuffer 机制,WebGL 调用会先被 Encode Command 到 Buffer 里面,然后在另外一个独立的 GPU 线程中 Decode Command,再调用相应的 GL API;
  2. 小游戏的主 Canvas 直接绘制在 GLSurfaceView 上,Chrome 会为每个 Canvas 元素分配额外的 Texture 作为 Render Target,然后再把该 Texture 合成到 Window 上,这意味着 Chrome 需要做一次 Render Target 的切换和多一次缓存拷贝,会增加一些 GPU 开销;

在 WebGL Aqua 这个 Demo 中,计算部分的开销很小,大部分是绘制的开销,Chrome 的多线程模型并没有带来多少并发的优势,只是抵消了 CommandBuffer 机制带来的一些 Overhead,不过额外的 Render Target 切换和缓存拷贝的影响看起来也很小,Chrome 和小游戏的性能基本持平,甚至 Chrome 还稍微好一些。如果是计算和绘制开销比较平均的场景,Chrome 可能会有更大的性能优势。

2D Canvas

Chrome 对比小游戏 2D Canvas 绘制的差别在于:

  1. Chrome 每一个 2D Canvas Draw Call,特别是 drawImage 的调用,因为浏览器运行环境复杂性的原因,有较大的 Overhead,包括 Image 对象的类型检查和转型,Dirty Rect 的计算,DOM 对象的交互,Image URL 的 Origin Check 安全检查,等等,而这些在小游戏运行环境下都是可以省略或者优化的;
  2. Chrome 使用 Skia 作为 2D 绘图引擎,Skia 作为一个通用,完备,可外部配置的 2D 绘图引擎,支持不同的光栅化后端实现(CPU,GL,Vulkan),支持复杂的内存管理和资源缓存机制,但是也带来了较高的 per drawImage 的开销,小游戏高度定制的 2D 绘图引擎可以容易地规避掉这些开销;

因为 Chrome 运行环境中较高的 per drawImage 的开销,我们可以在 Canvas Bitmap 测试中看到当 drawImage 的调用次数非常高时,Chrome 的 Renderer 线程会被严重阻塞而导致帧率下降幅度大大高于小游戏的下降幅度。

WebGL 理论上 Chrome 也会多一些 Overhead,只是 WebGL API 相比 2D Canvas API 的实现要简单很多,所以这些 Oveahead 实际影响非常小,并没有 2D Canvas 那么明显。

总结和优化建议

总结

  1. Chrome 和小游戏因为渲染流水线不同带来的影响很小,基本上可以忽略(在没有其他 DOM 元素的条件下);
  2. Chrome 和小游戏都使用 v8 作为 JavaScript 虚拟机,JavaScript 的计算性能基本一致;
  3. Chrome 和小游戏的 WebGL 渲染性能在都关闭抗锯齿的条件下基本一致,Chrome 还略微超出,另外 Chrome 可以通过降低渲染分辨率和使用 Instance Rendering 等方式进一步提升性能;
  4. Chrome 和小游戏在 2D Canvas 绘制场景中,如果 drawImage 的每帧调用次数在正常范围内,性能差别不大,如果 drawImage 调用次数非常高,Chrome 的性能下降幅度更大;

H5 游戏的优化建议

  1. 如果渲染场景比较复杂,WebGL 建议关闭抗锯齿,打开/关闭抗锯齿在 5.x 寸屏上对渲染效果的影响微乎其微,并且小游戏和原生手游也没有使用抗锯齿,关闭抗锯齿对于复杂的渲染场景可以带来非常明显的性能提升;
  2. 如果渲染场景非常复杂,可以考虑使用较低的渲染分辨率,降低分辨率可以带来明显的性能提升,600 ~ 720p 在 5.x 寸屏上比起原生分辨率虽然画面会略微模糊一些,但是整体渲染效果还是可以接受的;
  3. 如果渲染场景存在同一个 Mesh 的大量重复绘制,建议使用 Instance Rendering,Instance Rendering 可以大幅降低 GL API 调用次数,减少 GL API 调用的 CPU 开销,带来较大程度的性能提升;
  4. 如果 2D 游戏场景中的每帧 Image 绘制次数达到几千的量级,建议使用 WebGL 替代 2D Canvas(大部分 2D 游戏应该也就几百的量级,就不需要考虑这个);

如果觉得本文的内容对你有帮助,请麻烦点下赞

微信小游戏 - 小游戏 vs H5 游戏性能对比和分析相关推荐

  1. 好玩的h5游戏有哪些,H5游戏开发网站排行

    随着2021年即将进入最后一个季度,各类H5游戏开发网站年度排行也是逐步出炉,今天介绍的是TOM游戏平台,TOM游戏作为老牌的H5游戏开发网站和平台,今年内制作出了不少好玩的h5游戏,那么今年他们有哪 ...

  2. h5游戏搭建教程php,H5游戏幻梦西游:笑闹天宫搭建教程及演示

    利用韩国甲骨文作为前后端,腾讯轻量香港反代前后端加速. 演示站 环境要求 linux 1g内存以上 php5.6 mysql5.5 php7中gm工具无法创建数据表 mysql5.6以上服务端因为使用 ...

  3. 帝国CMS7.5仿《3500游戏》源码/大气H5游戏门户网站模板/H5游戏在线网站源码

    ☑️ 编号:ym219 ☑️ 品牌:帝国CMS7.5 ☑️ 语言:php ☑️ 大小:29.9MB ☑️ 类型:仿3500游戏 ☑️ 支持:门户网站模板

  4. 微信小游戏营销技巧讲解,TOM游戏微信营销平台-助力全行业H5营销

    为了达到持续关注.精准引流.带动分享的核心目的,企业的营销模式愈加多元化.近些年也涌现了诸如TOM游戏这类优质H5游戏开发商,那么TOM游戏平台是如何不断打造出爆款H5游戏的呢?而H5微信游戏营销的核 ...

  5. 小游戏与H5游戏对比与梳理

    H5游戏是运用了h5技术的响应式网站布局的游戏,它完全实现了网页游戏在手机移动端的无缝衔接.众所周知,H5游戏已盛行了多年,而如今,随着诸多小游戏的推出,小游戏爆款频出,从"跳一跳" ...

  6. 解密|小游戏与H5游戏的不同之处

    从"跳一跳"到"羊了个羊"微信小游戏上线4年时间,除了涌现出不少火爆全网的小游戏之外,也有类似于"动物餐厅"."口袋奇兵" ...

  7. 小程序游戏 vs h5游戏,技术优势分别有哪些

    从"跳一跳"到"羊了个羊"微信小游戏上线4年时间,除了涌现出不少火爆全网的小游戏之外,也有类似于"动物餐厅"."口袋奇兵" ...

  8. 浅显易懂的说清楚小游戏与H5游戏的区别

    从"跳一跳"到"羊了个羊"微信小游戏上线4年时间,除了涌现出不少火爆全网的小游戏之外,也有类似于"动物餐厅"."口袋奇兵" ...

  9. H5游戏开发之抓住小恐龙

    第一次写技术性博文,以前都只是写一些生活感想,记录一些生活发生的事情. 博主大三学生一枚,目前学习JS一年多,还处于学习阶段,有什么说的不好的希望大牛指点下,由于第一次写博文,排版什么的有待改进,希望 ...

最新文章

  1. apple id无法创建_我如何为我的Apple收藏夹创建网站
  2. 发现一款新一代项目管理软件
  3. 学好计算机科学的诀窍,【教学方法论文】计算机科学技术专业高效教学方法(共4295字)...
  4. 正则表达式的汉字匹配
  5. 斯坦福的著名小兔子模型的点云数据_传统方法的点云分割以及PCL中分割模块
  6. 使用MongoDB的MapReduce
  7. 面料经纬向、正反面判别方法
  8. 使用命令行 启动 各种服务(控制面板 开机启动项 注册表 等)
  9. DependencyProperty
  10. [Swift]LeetCode593. 有效的正方形 | Valid Square
  11. Win10技巧:如何确定电脑是否适用Hyper-V虚拟机?
  12. MSExchangeIS ID8528 日志提示邮箱已满报警
  13. 进销存系统收费标准是怎样的?
  14. 2019数字音乐市场年度回顾,QQ音乐全面领先
  15. python100天从新手到大师下载_GitHub - chenqiyi/Python-100-Days: Python - 100天从新手到大师...
  16. 用html实现彩虹动画
  17. 赵伟国回应华为“平衡者”标签:做个老二、老三也可以
  18. 【原】群晖btrfs系统修复
  19. 【嵌入式烧录/刷写文件】-5.1-详解map格式文件
  20. css 光影掠过文字效果

热门文章

  1. 0x3f3f3f3f 和0x3f3f3f3f3f3f3f3f
  2. iphone 6plus 输出的屏幕尺寸 375 ,667的原因 - 简书
  3. 远景能源面试+高管终面
  4. 数字时钟单片机程序c语言,单片机数字时钟C语言程序
  5. 基因测序与高通量测序区别
  6. 五款开源内容管理平台对比(免费部分):bolo/fastadmin/wordpress/zblog/redmine
  7. data.length提示undefined
  8. [激光器原理与应用-8]: 激光器电路的电磁兼容性EMC设计
  9. 欧洲CE认证电磁兼容EMC测试
  10. linux--redis的安装和配置和开启多个端口