Canvas 性能优化

最近对 html5小游戏有点兴趣,因为我感觉将来这个东西或许是前端一个重要的应用场景,例如现在每到某些节假日,像支付宝、淘宝或者其他的一些 APP可能会给你推送通知,然后点进去就是一个小游戏,基本上点进去的人,只要不是太抵触,都会玩上一玩的,如果要是恰好 get到用户的 G点,还能进一步增强业务,无论是用户体验,还是对业务的发展,都是一种很不错的提升方式。

另外,我说的这个 html5小游戏是包括 WebGLWebVR等在内的东西,不仅限于游戏,也可以是其他用到相关技术的场景,例如商品图片 360°在线查看这种,之所以从小游戏入手,是因为小游戏需要的技术包罗万象,能把游戏做好,再用相同的技术去做其他的事情,就比较信手拈来了

查找资料,发现门道还是蛮多的,看了一圈下来,决定从基础入手,先从较为简单的 canvas 游戏看起,看了一些相关文章和书籍,发现这个东西虽然用起来很简单,但是真想用好,发挥其该有的能力还是有点难度的,最好从实战入手

于是最近准备写个 canvas小游戏练手,相关 UI素材已经搜集好了,不过俗话说 工欲善其事必先利其器,由于对这方面没什么经验,所以为了避免过程中出现的各种坑点,特地又看了一些相关的踩坑文章,其中性能我感觉是必须要注意的地方,而且门道很多,所以整理了一下

使用 requestNextAnimationFrame进行动画循环

setTimeoutsetInterval并非是专为连续循环产生的 API,所以可能无法达到流畅的动画表现,故用 requestNextAnimationFrame,可能需要 polyfill

const raf = window.requestAnimationFrame
  || window.webkitRequestAnimationFrame
  || window.mozRequestAnimationFrame
  || window.oRequestAnimationFrame
  || window.msRequestAnimationFrame
  || function(callback) {
   
    window.setTimeout(callback, 1000 / 60)
  }

利用剪辑区域来处理动画背景或其他不变的图像

如果只是简单动画,那么每一帧动画擦除并重绘画布上所有内容是可取的操作,但如果背景比较复杂,那么可以使用 剪辑区域技术,通过每帧较少的绘制来获得更好的性能

利用剪辑区域技术来恢复上一帧动画所占背景图的执行步骤:

  • 调用 context.save(),保存屏幕 canvas的状态
  • 通过调用 beginPath来开始一段新的路径
  • context对象上调用 arc()rect()等方法来设置路径
  • 调用 context.clip()方法,将当前路径设置为屏幕 canvas的剪辑区域
  • 擦除屏幕 canvas中的图像(实际上只会擦除剪辑区域所在的这一块范围)
  • 将背景图像绘制到屏幕 canvas上(绘制操作实际上只会影响剪辑区域所在的范围,所以每帧绘制图像像素数更少)
  • 恢复屏幕 canvas的状态参数,重置剪辑区域

离屏缓冲区(离屏canvas)

先绘制到一个离屏 canvas中,然后再通过 drawImage把离屏 canvas 画到主 canvas中,就是把离屏 canvas当成一个缓存区。把需要重复绘制的画面数据进行缓存起来,减少调用 canvasAPI的消耗

const cacheCanvas = document.createElement('canvas')
const cacheCtx = cacheCanvas.getContext('2d')
cacheCtx.width = 200
cacheCtx.height = 200
// 绘制到主canvas上
ctx.drawImage(0, 0)

虽然离屏 canvas在绘制之前视野内看不到,但其宽高最好设置得跟缓存元素的尺寸一样,避免资源浪费,也避免绘制多余的不必要图像,同时在 drawImage时缩放图像也将耗费资源
必要时,可以使用多个离屏 canvas
另外,离屏 canvas不再使用时,最好把手动将引用重置为 null,避免因为 jsdom之间存在的关联,导致垃圾回收机制无法正常工作,占用资源

尽量利用 CSS

背景图

如果有大的静态背景图,直接绘制到 canvas可能并不是一个很好的做法,如果可以,将这个大背景图作为 background-image 放在一个 DOM元素上(例如,一个 div),然后将这个元素放到 canvas后面,这样就少了一个 canvas的绘制渲染

transform变幻

CSS

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值