- 微信小游戏的启动性能优化之首屏渲染
前言 微信小游戏云测试服务的开放之后,越来越多的开发者使用该功能测试自己的小游戏的性能。但是大部分小游戏的测试结果显示,启动性能得分很低,远远达不到80分的标准线,甚至难以达到60分。 [图片] 根据微信小游戏文档中的启动优化最佳实践,优化思路一共有6种: 精简首包资源 分包加载 引擎插件 预下载能力 降低首屏渲染资源 尽快渲染。 常规的优化思路往往是两步: 拆分代码包,精简首包资源,使得首包只存首屏图片和一个加载进度条及相关代码; 使用分包加载。 根据小游戏的启动时序,会发现,降低代码包资源会减少了代码包下载,以及在某种程度下降低JS注入耗时。 [图片] 然而,即使启动优化到这一步,很多小游戏依旧得不到理想的分数。因为使用引擎开发的小游戏,即便只留首包必要资源,也会保留引擎代码,这无非会增加很长时间的JS注入耗时,以及首屏渲染耗时也未得到优化。此时很多开发者已经非常苦恼:我该如何优化呐? 自然而然,解决思路无非是,1. 降低注入代码的大小来减少JS注入耗时; 2. 简化首屏渲染逻辑,比如不依赖第三方引擎进行轻量渲染。但是,怎么做呐? 本文,将结合上面的两个解决思路,提供一套不依赖引擎(WebGL/Canvas2D直接渲染首屏)的小游戏首包加载套路,即减少了引擎代码注入耗时,又避免了第三方引擎的重度渲染。该方式可以直接套用,使用后的小游戏的启动性能在云测试报告下的启动性能得分能达到90及以上。 背景 目前微信官方文档、微信小游戏社区和各个引擎社区已经有很多篇关于启动优化的文章。除了微信官方文档,在微信小游戏社区和cocos 社区下有两篇非常优秀的使用WebGL渲染首屏的文章: 小游戏首屏启动优化 Cocos Creator 微信小游戏平台启动与包体优化(首屏渲染耗时降低 50%) 尤其是第二篇,很多开发者都查资料时查到这一篇文章,按照这篇文章的逻辑来优化小游戏能够达到很理想的效果,本文的思路也是基于该文章之上进一步优化。这两篇文章均是直接使用WebGl渲染首屏,能够达到很理想的效果。强烈先去看一眼这两篇文章及下面的评论,基本上遇到的所有问题都有解答。 但是二者有着各自的缺陷: 第一篇文章简练地介绍了优化思路,但是直接使用的话需要理解WebGL的逻辑并进行改造,存在难度; 第二篇文章是一片很优秀的文章,大家可以先学习一下。该文章中的代码虽然可以直接使用套用,但是代码逻辑和gl渲染的使用方式存在一定的错误,比如重复创建图片,未使用rAF渲染等,这些错误会导致微信客户端统计启动耗时出现异常。然而,因为对gl改写的难度比较大,所以,本文基于第二篇文章中的WebGL渲染首屏的代码进行了改造,附上了正确的使用方式,并额外新增了一份使用Canvas2D渲染首屏的代码。 代码片段 话不多说,附上代码片段: 1. WebGL渲染 webGL代码理解起来还是有难度的,所以代码中的 [代码]webgl_first_render.js[代码]可以直接使用,使用方式可以参考[代码]game.js[代码]。这段代码解决了文章二中的云测启动耗时统计错误、启动黑屏、横屏渲染错误、内存泄漏、屏幕闪烁等异常情况。 代码片段如下: https://developers.weixin.qq.com/s/tknkPjmr7Glg 2. Canvas2D渲染 Canvas2D渲染使用CanvasRenderingContext2D对象 直接渲染。实现上很简单,改造起来也很容易。其实现逻辑是和webgl是一样的。 代码片段如下: https://developers.weixin.qq.com/s/QWno6jmW7Ylx
2020-10-23 - 华为Android必现:离屏webgl 渲染到 2D canvas的黑屏问题
- 当前 Bug 的表现(可附上截图) 注:目前只有华为的手机和平板会有这个问题。其他手机:Android,iOS都正常表现。 用离屏的webgl canvas渲染到上屏的canvas 2D环境,只有在华为的android手机上,看不到webgl的内容。 下图中,彩色的三角形和四边形,就是用webgl渲染的;但是看不到; [图片] - 预期表现 [图片] - 复现路径 https://developers.weixin.qq.com/s/L4gO2NmP7d6B - 提供一个最简复现 Demo https://developers.weixin.qq.com/s/L4gO2NmP7d6B 重点代码在最后几行。 [代码]function[代码] [代码]tick() {[代码][代码] [代码][代码]requestAnimationFrame(tick);[代码][代码] [代码][代码]drawScene();[代码][代码] [代码][代码]animate();[代码] [代码] [代码] [代码] // 将3D纹理拷贝到2D纹理上。[代码] [代码] contextMain[代码][代码].clearRect(0 ,0, canvasMain.width, canvasMain.height);[代码][代码][代码] contextMain[代码].drawImage(canvas3D, 0, 0);[代码][代码] [代码][代码][代码]contextMain[代码].fillStyle = [代码][代码]"#FFFFFF"[代码][代码] [代码][代码][代码]contextMain[代码].fillRect(0, 0, 100, 100);[代码][代码]}[代码] let contextMain = undefined; [代码]let canvasMain = undefined;[代码][代码]let canvas3D = undefined;[代码] [代码]function[代码] [代码]webGLStart(canvas) {[代码] [代码] [代码][代码]canvasMain = canvas;[代码] [代码] contextMain= [代码]canvasMain.getContext([代码][代码]'2d'[代码][代码]);[代码][代码] [代码][代码] [代码][代码] [代码][代码] // 创建离屏webgl环境[代码][代码] [代码] [代码][代码]canvas3D = wx.createCanvas();[代码][代码] [代码][代码]canvas3D.width = canvasMain.width;[代码][代码] [代码][代码]canvas3D.height = canvasMain.height[代码] [代码] [代码][代码]initGL(canvas3D);[代码][代码] [代码][代码]initShaders();[代码][代码] [代码][代码]initBuffers();[代码] [代码] [代码][代码]gl.clearColor(0.0, 0.0, 0.0, 1.0);[代码][代码] [代码][代码]gl.enable(gl.DEPTH_TEST);[代码] [代码] [代码][代码]tick();[代码][代码]}[代码] [代码]GameGlobal.alert = (...msg) => console.log([代码][代码]"alert"[代码][代码], ...msg);[代码] [代码]webGLStart(wx.createCanvas());[代码]
2019-03-11 - 【周知】Android 端将调整小游戏 “在屏 Canvas” 的放缩策略
Hi all, 之后的版本中,微信 Android 端将调整 “在屏 Canvas” 的放缩策略,与 iOS 保持一致。请游戏开发者提前做好适配工作,该修改可能导致游戏界面模糊的问题。望周知。 1. 问题描述 在之前的版本中,小游戏中,第一个 Canvas 即 “在屏Canvas” ,无论开发者怎样设置 width height,在底层都会将width height放缩为物理像素。(gl.viewport gl.scissor 等接口的底层,我们也做了对应的放缩,所以开发者感知不到这个逻辑) 这种放缩,会让在屏Canvas无论如何设置 size 都是最清晰的状态。 但是,这种放缩会使得渲染相对较慢,而有些游戏并不需要这种清晰度;同时也给一些重度游戏在使用 shader 接口时埋了坑,给游戏开发造成了不必要的困难。 所以我们决定在之后的版本中,Android端去掉这个放缩逻辑,与 iOS 保持一致。 2. 如何适配 下面用代码举例:在一台 wx.getSystemInfo 中返回 screenWidth = 360 screenHeight = 640 pixelRatio = 3 的机器上。在之前的版本中,你直接绘制文字就是清晰的。现在则需要主动设置 canvas.width = screenWidth * pixelRatio; canvas.height = screenHeight * pixelRatio; 才能和之前达到一样的效果。 另外,对 “在屏 canvas” 的 width/height 的任何修改和适配,这种适配都不会影响游戏在老版本上的运行 如果你使用一些游戏引擎,请查阅游戏引擎的文档,如 cocos ,不需要自己修改 canvas 的宽高,只需要设置 setRetinaEnable(true) p.s. 我们自查发现大部分游戏,游戏主场景是没有问题的,但一些 loading 场景,则会有模糊的现象。请注意一下。
2018-12-26