canvas 的动画卡顿问题(运行一段时间卡顿)

最近公司有项目需要写纯canvas组件,所以花了一段时间学习了下canvas。 canvas这东西上手简单,精通难。而且也很少纯canvas写,所以网上参考的内容也比较少。

这里记录我用canvas遇到的一个坑,canvas运行一段时间卡顿。

为了给你们省时间,我先直接放解决办法。想看问题分析的步骤和方法可以看下去。

canvas中使用的save()数量和restore()的数量一致就能解决问题。 记得点个赞再走

问题描述:

canvas写的动画效果,刚运行是很正常,但是一段时间(差不多2分钟)后速度会很慢,这里直接上图看效果。

刚运行时:

运行一段时间(差不多2分钟)后

对,你没看错,这就是现在的运行速度

可以看到,运行一段时间后,速度变得非常慢,那么先分析下代码:

解决这个问题,起初时没有任何头绪,翻阅百度谷歌都没有找到解决办法,只好自己又去分析问题。

分析问题:

恰巧,分析问题分析到块下班了,准备关电脑下班了,结果,在关闭浏览器标签页的时候发现了问题,平常点击关闭按钮就会瞬间关闭的标签页,在我关闭正在写的页面的时候居然卡了2秒左右才关闭,我又打开页面试了下发现,页面刚打开是关闭,时瞬间关闭的,但是运行到canvas动画速度变慢的时候关闭,就会出现先卡顿一下再关闭的情况。

所以,我就看了下浏览器的性能占用,下面直接放图。 刚运行时的内存占用:30MB

然后我看着从30MB一路上升到接近80MB的内存占用,陷入可沉思。 运行一段时间后的内存占用:30MB

我好像发现了原因,是内存爆了。我以为是window.requestAnimationFrame搞的鬼,然后就在该次动画运行后,下次动画运行前用window.cancelAnimationFrame停掉了该次动画,结果还是无济于事。我又想,难道canvas有什么方法会把参数写到内存?等等,save()不就是吗?看下官方文档。

好家伙,应该就是你搞的鬼了。 save()的作用是把参数写到栈内存种,需要的时候用restore()拿取。所以就是我放入内存的参数大于我拿取的参数,导致内存爆了?试一试就知道了。 我发现在上面的代码中用了5个save(),但是restore()只用了4个。我删掉了最下面的ctx.save(),在运行一段时间看看内存变化。

这下内存占用稳定到了20MB左右,CPU占用也从30%直接掉到了2%。我又让动画运行了20多分钟,依然没有变慢,好了,大功告成,问题就是save()引起的了,只要放入内存的参数(save())数量和拿取的参数restore()数量一致,就不会出现相同的问题。

代码写的可能不是很规范,而且我也还是个新手,大佬饶命