canvas教程

提高HTML5 canvas性能的几种方法(转)(2)

字号+ 作者:H5之家 来源:H5之家 2017-05-08 12:01 我要评论( )

例如,如果你使用多种填充色来渲染一个场景,按照不同的颜色分别渲染要比通过canvas上的布局来进行渲染要更加节省资源。为了渲染一副条纹的图案,你可以这样渲染:用一种颜色渲染一条线条,然后改变颜色,渲染下一

例如,如果你使用多种填充色来渲染一个场景,按照不同的颜色分别渲染要比通过canvas上的布局来进行渲染要更加节省资源。为了渲染一副条纹的图案,你可以这样渲染:用一种颜色渲染一条线条,然后改变颜色,渲染下一条线条,如此反复:

[javascript] view plaincopy

也可以先用一种颜色渲染所有的偶数线条再用另外一种染色渲染所有的基数线条:

[javascript] view plaincopy

下面的性能测试用例分别用上边两种方法绘制了一副交错的细条纹图案(jsperf):


正如我们预期的,交错改变状态的方法要慢的多,原因是变化状态机是有额外开销的。


4.RENDER SCREEN DIFFERENCES ONLY, NOT THE WHOLE  NEW STATE

这个很容易理解,在屏幕上绘制较少的东西要比绘制大量的东西节省资源。重绘时如果只有少量的差异你可以通过仅仅重绘差异部分来获得显著的性能提升。换句话说,不要在重绘前清除整个画布。:

[javascript] view plaincopy

  • context.fillRect(0, 0, canvas.width, canvas.height);  
  • 跟踪已绘制部分的边界框,仅仅清理这个边界之内的东西:

    [javascript] view plaincopy

  • context.fillRect(last.x, last.y, last.width, last.height);  
  • 下面的测试用例说明了这一点。该测试用例中绘制了一个穿过屏幕的白点(jsperf):


    如果您对计算机图形学比较熟悉,你或许应该知道这项技术也叫做“redraw technique”,这项技术会保存前一个渲染操作的边界框,下一次绘制前仅仅清理这一部分的内容。

    这项技术也适用于基于像素的渲染环境。这篇名为JavaScript NIntendo emulator tallk的文章说明了这一点。


    5.USE MUTIPLE LAYERED CANVASES FOR COMPLEX SCENES

    我们前边提到过,绘制一副较大的图片代价是很高昂的因此我们应尽可能的避免。除了前边讲到的利用另外得不可见的canvas进行预渲染外,我们也可以叠在 一起的多层canvas。图哦你的过利用前景的透明度,我们可以在渲染时依靠GPU整合不同的alpha值。你可以像如下这么设置,两个绝对定位的 canvas一个在另一个的上边:

    [javascript] view plaincopy

    相对于仅仅有一个canvas的情况来讲,这个方法的优势在于,当我们需要绘制或者清理前景canvas时,我们不需要每次都修改背景 canvas。如果你的游戏或者多媒体应用可以分成前景和背景这样的情况,那么请考虑分贝渲染前景和背景来获取显著的性能提升。下面的图表比较了只有一个 canvas的情况和有前景背景两个canvas而你只需要清理和重绘前景的情况(jsperf):


    你可以用相较慢的速度(相对于前景)来渲染背景,这样便可利用人眼的一些视觉特性达到一定程度的立体感,这样会更吸引用户的眼球。比如,你可以在每一帧中渲染前景而仅仅每N帧才渲染背景。

    注意,这个方法也可以推广到包含更多canvas曾的复合canvas。如果你的应用利用更多的曾会运行的更好时请利用这种方法。


    6.AVOID SHADOWBLUR

    跟其他很多绘图环境一样,HTML5 canvas允许开发者对绘图基元使用阴影效果,然而,这项操作是相当耗费资源的。

    [javascript] view plaincopy

    下面的测试显示了绘制同一场景使用何不使用阴影效果所带来的显著的性能差异(jsperf):



    7.KNOW VARIOUS WAYS TO CLEAR THE CANVAS

    因为HTML5 canvas 是一种即时模式(immediate mode)的绘图范式(drawing paradigm),因此场景在每一帧都必需重绘。正因为此,清楚canvas的操作对于 HTML5 应用或者游戏来说有着根本的重要性。

    正如在 避免 canvas 状态变化的一节中提到的,清楚整个canvas的操作往往是不可取的。如果你必须这样做的话有两种方法可供选择:调用

    [javascript] view plaincopy

  • context.clearRect(0, 0, width, height)  
  • 或者使用 canvas特定的一个技巧

    [javascript] view plaincopy

  • canvas.width = canvas.width  
  • 在书写本文的时候,cleaRect方法普遍优越于重置canvas宽度的方法。但是,在某些情况下,在Chrome14中使用重置canvas宽度的技巧要比clearRect方法快很多(jsperf):


    请谨慎使用这一技巧,因为它很大程度上依赖于底层的canvas实现,因此很容易发生变化,欲了解更多信息请参见 Simon Sarris 的关于清除画布的文章。


    8.AVOID FLOATING POINT COORDINATES

    HTML5 canvas 支持子像素渲染(sub-pixel rendering),而且没有办法关闭这一功能。如果你绘制非整数坐标他会自动使用抗锯齿失真以使边缘平滑。以下是相应的视觉效果(参见Seb Lee-Delisle的关于子像素画布性能的文章)


    如果平滑的精灵并非您期望的效果,那么使用 Math.floor方法或者Math.round方法将你的浮点坐标转换成整数坐标将大大提高运行速度(jsperf):


    为使浮点坐标抓换为整数坐标你可以使用许多聪明的技巧,其中性能最优越的方法莫过于将数值加0.5然后对所得结果进行移位运算以消除小数部分。

    [javascript] view plaincopy

    两种方法性能对比如下(jsperf):


    9.OPTIMIZE YOUR ANIMATIONS WITH ‘REQUESTANIMATIONFRAME’

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • 前端的有关IE兼容性的问题(图片的下载)

      前端的有关IE兼容性的问题(图片的下载)

      2017-05-08 13:00

    • tkinter-canvas的问题,Python交流,技术交流区,鱼C论坛

      tkinter-canvas的问题,Python交流,技术交流区,鱼C论坛

      2017-05-07 14:20

    • HTML5网页中SVG和Canvas以及IMG图片的转换方法

      HTML5网页中SVG和Canvas以及IMG图片的转换方法

      2017-05-06 09:05

    • 学习使用Canvas绘图

      学习使用Canvas绘图

      2017-05-05 17:03

    网友点评