7) 改进性能
requestanimationframe确实是实现动画不可或缺的利器,但是不可以过度的使用。尤其是和一些渐变性的事件相关联的动画,比如,chrome web store首页利用垂直滚轴不断显示页面内容。下面给出一个不太好的例子:
function onscroll() {
update();
}
function update() {
// assume domelements has been declared
// by this point :)
for(var i = 0; i < domelements.length; i++) {
// read offset of dom elements
// to determine visibility - a reflow
// then apply some css classes
// to the visible items - a repaint
}
}
window.addeventlistener(‘scroll’, onscroll, false);
上面这个例子,每次scroll事件的时候,都调用requestanimationframe,虽然浏览器会量力而行的执行动画渲染,但是有两个冲突的地方,成为了动画渲染的性能瓶颈。首先,scroll事件调用的频率,远远大约每秒60帧。也就是说,浏览器会缓存大量的requestanimationframe事件,导致很多的update函在做无用功。其次,在每次执行requestanimationframe的时候,里面对dom元素的属性进行了修改,引起了很多的reflow和repaint事件,显然完成所有的reflow和repaint时间的远远超过16ms。
为了解决第一个问题,首先要将scroll和requestanimaitonframe函数分离,修改后的代码如下:
var latestknownscrolly = 0;
function onscroll() {
latestknownscrolly = window.scrolly;
}
function update() {
requestanimationframe(update);
var currentscrolly = latestknownscrolly;
// read offset of dom elements
// and compare to the currentscrolly value
// then apply some css classes
// to the visible items
}
// kick off
requestanimationframe(update);
上面的代码,scroll事件仅负责将最新的窗口位置,赋值给一个变量。这样的话,可以避免大量的requestanimationframe事件被缓存,从而真正让requestanimationframe按照浏览器的能力,进行动画渲染。
对于第二个问题,唯一的办法,尽量的减少repaint和reflow的事件。道理虽然简单,但是优化难度很大,要求读者对于dom的渲染的每个函数都非常熟悉。下面列出几篇文章,仅供参考:
classlist for great good.
breakdown of repaint.
learning from twitter
(未完待续)
以上就是html5游戏开发 之 循环的控制(3)的内容。