HTML5游戏开发 之 循环的控制(3)

时间:2016-02-29
       7) 改进性能

       RequestAnimationFrame确实是实现动画不可或缺的利器,但是不可以过度的使用。尤其是和一些渐变性的事件相关联的动画,比如,Chrome Web Store首页利用垂直滚轴不断显示页面内容。下面给出一个不太好的例子:

  1. function onScroll() {
  2. update();
  3. }
复制代码
  1. function update() {

  2. // assume domElements has been declared
  3. // by this point :)
  4. for(var i = 0; i < domElements.length; i++) {

  5. // read offset of DOM elements
  6. // to determine visibility - a reflow

  7. // then apply some CSS classes
  8. // to the visible items - a repaint

  9. }
  10. }
复制代码
  1. window.addEventListener(‘scroll’, onScroll, false);
复制代码

       上面这个例子,每次scroll事件的时候,都调用RequestAnimationFrame,虽然浏览器会量力而行的执行动画渲染,但是有两个冲突的地方,成为了动画渲染的性能瓶颈。首先,scroll事件调用的频率,远远大约每秒60帧。也就是说,浏览器会缓存大量的RequestAnimationFrame事件,导致很多的update函在做无用功。其次,在每次执行RequestAnimationFrame的时候,里面对dom元素的属性进行了修改,引起了很多的Reflow和Repaint事件,显然完成所有的Reflow和Repaint时间的远远超过16ms。

       为了解决第一个问题,首先要将scroll和RequestAnimaitonFrame函数分离,修改后的代码如下:

  1. var latestKnownScrollY = 0;
  2. function onScroll() {
  3. latestKnownScrollY = window.scrollY;
  4. }

  5. function update() {
  6.   requestAnimationFrame(update);
  7.   var currentScrollY = latestKnownScrollY;

  8.   // read offset of DOM elements
  9.   // and compare to the currentScrollY value
  10.   // then apply some CSS classes
  11.   // to the visible items
  12. }

  13. // kick off
  14. requestAnimationFrame(update);
复制代码

       上面的代码,scroll事件仅负责将最新的窗口位置,赋值给一个变量。这样的话,可以避免大量的RequestAnimationFrame事件被缓存,从而真正让RequestAnimationFrame按照浏览器的能力,进行动画渲染。

       对于第二个问题,唯一的办法,尽量的减少Repaint和Reflow的事件。道理虽然简单,但是优化难度很大,要求读者对于Dom的渲染的每个函数都非常熟悉。下面列出几篇文章,仅供参考:

       ClassList for great good.

       Breakdown of repaint.

       Learning from Twitter

       (未完待续)

       上文:

       HTML5游戏开发 之 循环的控制(2)

       HTML5游戏开发 之 循环的控制(1)

        HTML5 游戏开发 之 资源加载篇(2)

        HTML5 游戏开发 之 资源加载篇(1)


上一篇:HTML5游戏开发 之 循环的控制(2) 下一篇:百行 HTML5 代码实现四种双人对弈游戏

相关文章

最新文章