canvas简介以及常用性能优化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了canvas简介以及常用性能优化相关的知识,希望对你有一定的参考价值。

参考技术A

HTML5 的 Canvas 元素使用 JavaScript 在网页上绘制图像。
画布是一个矩形区域,您可以控制其每一像素。
Canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。
Canvas 是逐像素进行渲染的。
在 Canvas 中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。

SVG 基于 XML,这意味着 SVG DOM 中的每个元素都是可用的。您可以为某个元素附加 JavaScript 事件处理器。
在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象的属性发生变化,那么浏览器能够自动重现图形。

- 依赖分辨率
- 不支持事件处理器
-弱的文本渲染能力
- 能够以 .png 或 .jpg 格式保存结果图像
- 最适合图像密集型的游戏,其中的许多对象会被频繁重绘

-不依赖分辨率
- 支持事件处理器
-最适合带有大型渲染区域的应用程序(比如谷歌地图)
- 复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
- 不适合游戏应用

当我们在绘制的一个元素(文字、图形)的时候,首先要对这个元素规定它的颜色,文字字体,然后在进行绘制,不然不会生效。

场景 :假设您有一个游戏,其UI位于顶部,中间是游戏性动作,底部是静态背景。

方法 :可以将游戏分成三个<canvas>层。 UI将仅在用户输入时发生变化,游戏层随每个新框架发生变化,并且背景通常保持不变

好处 :避免了固定组件的重复渲染。

设备屏幕上的像素(逻辑像素),我们可以当做是正常的像素(css中设置的像素),你可以正常使用它。如果你画一个100px的东西,他也就是一个100px的东西。但是,在出现了一些高分辨率屏幕的手机之后,一个属性devicePixelRatio就一起出现了。它允许我们去查询设备像素比。在这里我们需要抛出一个名词逻辑像素,也就是在css设置的100px时,在iphone6/7/8(devicePixelRatio为3)上,实际渲染的是300px的物理像素。比例为3:1

但是这对于我们开发者的影响是什么呢?早些时候,我们注意到当我们向这种高分辨率的屏幕添加img的时候,我们的图形受到devicePixelRatio的影响变得非常模糊。
如何解决这个问题呢?如果我把img的宽和高分别与devicePixelRatio相乘,得到的大小画进屏幕中,在对齐进行缩放devicePixelRatio的大小。Img就会以一种高清的方式呈现。

但是此方法有个问题就是既然同比将画布和内容进行了放大,然后在进行缩放,那么绘制出来的图片大小就会相应的增大。建议根据需求来判断是否需要进行高清操作。

canvas动画的本质是不断地擦除和重绘,再结合一些时间控制的方法达到动画的目的
显示器刷新频率是60Hz,最平滑动画的最佳循环间隔是1000ms/60,约等于16.6ms
requestAnimationFrame 就是根据显示器刷新频率来的,这是浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,节省系统资源,提高系统性能,如果页面不是激活状态下的话, requestAnimationFrame() 会被暂停调用以提升性能和电池寿命。

执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,返回一个 requestID,该回调会在浏览器下一次重绘之前执行

取消一个先前通过调用window. cancelAnimationFrame()方法添加到计划中的动画帧请求,接受一个 requestID
浏览器兼容

canvas每条线都有一条无限细的中线,线由中线两个伸展。

解决问题的根源起点应该在0.5的地方,这也是为什么x,y需要+0.5。当x,y做过计算不一定是整数的时候可能+0.5又出现模糊的情况。所以做一个取整可以保证不会出现模糊的情况

由于我们具备「把图片中的某一部分绘制到 Canvas 上」的能力。
在平常的html中,我们会把多个对象放在一张图片里面,以减少请求数量。这通常被称为「精灵图」。然而,这实际上存在着一些潜在的性能问题。 使用 drawImage 绘制同样大小的区域,数据源是一张和绘制区域尺寸相仿的图片的情形 ,和比起 数据源是一张较大图片(我们只是把数据扣下来了而已)的情形 ,前者的开销要小一些。可以认为,两者相差的开销正是「裁剪」这一个操作的开销。
虽然看上去开销相差并不多,但是 drawImage 是最常用的 API 之一,我认为还是有必要进行优化的。优化的思路是,将「裁剪」这一步骤事先做好,保存起来,每一帧中仅绘制不裁剪。

我们可以先把待绘制的区域裁剪好,保存起来,这样每次绘制时就能轻松很多
drawImage 方法的第一个参数不仅可以接收 Image 对象,也可以接收另一个 Canvas 对象。而且,使用 Canvas 对象绘制的开销与使用 Image 对象的开销几乎完全一致。我们只需要实现将对象绘制在一个未插入页面的 Canvas 中,然后每一帧使用这个 Canvas 来绘制。

canvas/webgl测试数据稳定性专项优化优秀实践

背景


Canvas/webgl测试的是浏览器内核的渲染能力。通常会选取一些业界常用的测试页面作为测试用例,例如:

图1webgl测试页面截图

Canvas/webgl测试从列入TBS(腾讯浏览服务)上线前性能测试以来,就一直存在测试数据不稳定问题。初期采用购置小风扇、增加冷却时间、编写重测页面等方法解决问题,效果并不理想。时不时还是会出现测试结果发现性能落后,但开发跟进分析后发现是测试数据波动导致的误报的情况。这种情况对测试和开发同学的工作效率都造成影响。


问题定位


TBS(腾讯浏览服务英文缩写)3.3的上线前性能测试再次测得webgl落后。webglspacerocks用例落后上一版本(TBS3.2)2.59帧。但经过开发定位问题,发现依然是数据波动导致的误报。

canvas/webgl测试数据稳定性专项优化优秀实践

 表1webgl性能测试结果

这次,开发同学和测试同学决定刨根问底找到影响数据波动的根本原因。

通过perfMon性能监控工具,我们发现发热导致的cpu降频和cpu关闭是影响测试结果的主要原因。    

canvas/webgl测试数据稳定性专项优化优秀实践

 图2开发定位问题邮件内容


解决办法


为此,测试组专门购置了性能优越的笔记本散热风扇来给测试手机降温。

canvas/webgl测试数据稳定性专项优化优秀实践

图3笔记本散热风扇

初步验证发现效果良好(下面一段文字为邮件内容节选):

“本周blink3.0 canvas/webgl性能日常监控结果:

数据基本稳定。在增加了散热器与小风扇辅助散热之后,三部手机的测试结果均接近3、4月份结果且多多少少有所提升,无重测项。”


优化效果


日常监控历史记录可以看到优化前后的效果:

1、6个用例的波动范围都不同程度缩小。其中GUIMark3 GM3_JS_Compute的波动从9帧缩小为0.2帧。

canvas/webgl测试数据稳定性专项优化优秀实践

图4优化前后数据波动范围对比

2、之前经常要重测的用例,如今不再需要重测。目前重测概率为0。

测试项目

优化前重测概率
(统计近5次结果)

优化后重测概率
(统计近2次结果)

GM3_JS_Bitmap

0%

0%

GM3_JS_Vector

0%

0%

GM3_JS_Compute

20%

0%

webgl_shader2

0%

0%

webgl_materials

24%

0%

webglspacerocks

40%

0%


表2优化前后重测记录

注:当监控数据和上一次相差2帧或以上时需要重测。


规范“有效落后”门限值


注:达到该门限值才认为是有效落后,开发跟进分析。

6个用例当中,GUIMark3 GM3_JS_Compute的波动最大。所以我们对GUIMark3 GM3_JS_Compute进行了4次测试(每次10组测试值)验证数据波动范围:

测试组

GUIMark3 GM3_JS_Compute

3min-1

3min-2

6min-1

6min-2

平均

53.607

53.266

52.785

53.773

最大最小差

0.9

0.99

0.87

0.92

最大

53.95

53.74

53.11

54.19

最小

53.05

52.75

52.24

53.27

表3优化后数据波动情况

canvas/webgl测试数据稳定性专项优化优秀实践

图5优化后数据波动情况

结论:

1、单次测试10组数据的最大最小值偏差月1帧;

2、多次测试10组数据的平均值波动在0.5帧左右;

3、多次测试所有数据的最大最小值偏差1.95帧。

基于以上测试结果,制定不同用例的“有效落后”门限值如下:

测试项目

“有效落后”门限值

GM3_JS_Bitmap

    1帧

GM3_JS_Vector

    1帧

GM3_JS_Compute

    2帧

webgl_shader2

    1帧

webgl_materials

    1帧

webglspacerocks

    1帧


表5根据数据波动验证结果制定“有效落后”门限值


canvas/webgl测试数据稳定性专项优化优秀实践

canvas/webgl测试数据稳定性专项优化优秀实践




长按指纹识别图中的二维码,获取更多测试干货分享!



canvas/webgl测试数据稳定性专项优化优秀实践  
canvas/webgl测试数据稳定性专项优化优秀实践


以上是关于canvas简介以及常用性能优化的主要内容,如果未能解决你的问题,请参考以下文章

性能优化简介

原生canvas游戏性能优化

深入解析G1垃圾收集器与性能优化

IDEA最全最常用的配置与性能优化(Java必备)

canvas性能优化总结

阿里P8架构师谈:应用后端+移动端的性能优化指标,以及性能优化方法