你不知道的canvas ——性能优化篇(1)
2024-06-24小知识,大挑战!本文正在参与?程序员必备小知识?创作活动?本文同时参与?「掘力星计划」 ,赢取创作大礼包,挑战创作激励金
大家好, 我是Fly哥 ,这是本月输出文章的第三篇了,每个月原创四篇这是我给自己的要求,不会辜负大家对公众号前端图形的喜欢。 好了现在进入今天的主题: canvas 性能优化, 读完本篇文章你可以学到下面:
- 哪些因素会影响canvas的性能
- 如何优化canvas
我们都知道浏览器上渲染动画 每一秒高达60帧,也就是1秒钟内我们完成60次图像绘制, 也就是每一帧图像的绘制时间其实就是(1000/ 60)。 如果在每一帧动画的时间小于 16.7 ms 辣么就会出现卡顿、丢帧。而canvas 其实是一个指令式绘图系统, 他通过绘图指令来完成绘图操作。 那么很容易想到两个很关键的因素:
- 绘制图形的个数
- 绘制图形的大小
很容易理解,假设绘制 绘制一个图形 几毫秒 那么如果绘制10000个图形呢?? 肯定时间就长了, 如果后面其他操作、ui交互、渲染其他图形... 这就会导致渲染的时间比较长了。canvas 绘制的图像都是一个个小像素点构成的、 你绘制一个半径为5 的圆 和半径为1000的圆所需要的像素点 肯定是不一样的。这里给大家看一张图清晰的明白一个绘制的构成。
图片
你图形数量越大需要的像素点就越多,那么 片元着色器就要不断的去执行。
我写了两个小demo 来验证我们的猜想,纸上得来终觉浅,绝知此事要躬行哇!
主要是绘制100个 和绘制10000个小球作对比
我们先看下代码:
绘制100 个小球的fps 还是能够稳定在30fps 的如图:
100个
100个
绘制10000个小球的fps 掉帧的厉害 是真的卡。 所以也就验证了我们的猜想 ,canvas 的性能是和绘制图形个数有关系的
这个fps 帧率显示器是 chrome 自带的 输入 command + shift + p 搜索 render fps 自然就找到了。
我们再来验证绘制图形的大小会不会影响fps 。我将小球的数量改成1000, 半径改成10 。
目前的小球的数量 是1000 , 半径大小是10。
我们看下gif 图:
Oct-24-2021 20-23-40
我们看到帧率大概是稳定在30fps 的, 这时候 数量不变的情况下,我将小球的半径改成200, 我们在看下帧率变化,然后呢 你会看到帧率有较为明显的下跌。 如图:
Oct-24-2021 20-24-16
所以总结以上来看,影响canvas的因素就是有以上两点:
- 第一个渲染的图形数量
- 第二个就是渲染图形的大小
其实我来深度分析, 第一个渲染的图形数量多,就是调用绘图指令的次数比较多,
第二个渲染的图形大,就是一次绘图渲染的时间比较长
然后下面我就开始优化canvas
这句话怎么理解呢 , 假设你要在场景中画正n变形,这是一个 很常见的需求可能你稍不注意写下了下面这几行代码:
points 对应的生成多边形的点,代码如下:
主要是根据一个圆心,根据边数生成对应的点。
乍一看这代码没什么问题,生成一个正多边形, 这时候我在页面上画了1000个正多边形: 如下图:
优化前
一看这fps低成这个样子,很多人这时候说,你画的图形多,那我只要悄悄的改下代码,就能让fps 回归正常
我又重写了正多边形的方法:
我们看下这时候的fps 帧率:
优化后
看了下fps 已经成功升到了30fps, 这是为什么呢, 第一段我们在循环中去做绘图操作, 循环一次, stoke() 一次,这显然是不合理的,第二个直接把stoke() ,放到循环外,其实就调用了一次,所以我们可以得出减少绘图指令是可以提高canvas的性能的
关注我的公众号 「「前端图形」」,获取更多好玩与有趣的图形知识。「如果你也一样对技术热爱,喜欢「图形、数据可视化、游戏」并且为之着迷,欢迎加我个人微信(wzf582344150)「,将会邀请你加入我的」可视化交流学习群一起面向快乐编程~」 。 「我是Fly」, 目前在某电商公司互动游戏组。在这个互联网技术疯狂快速迭代的时代中,很高兴能和你一起变强!