郑重申明,以下只是本人的理解。没有实践论证,引用者小心!我不希望有人被我坑!
传统的js动画是通过setTimeout循环调用实现。
setTimeout调用一次将引起页面的改变,即页面将重绘。问题一,如果setTimeout调用频率过高会发生什么情况呢?
杯具的16ms,在早期。js的callback执行,是依赖CPU的中断来进行控制的,如果两个中断之间时间太短会导致,CPU性能消耗很高,同时影响能耗,于是微软和英特公司为了解决这个问题,就约定每个中断之间的间隔是15.6ms(64 fps)所以就是我们常见的约等于16ms的间隔。
不过随着web的要求不断增加,大家对这个要求希望是放宽的态度,于是在高端浏览器,这个性能被提升了4倍左右,所以在chrome,ie10等浏览器,setTimeout的间隔缩短到了 4ms (250 fps)。(换句话说,setTimeout是一个可以不停切换函数调用的函数,在计算机中,函数的切换cpu会产生中断,如果切换很快,势必会引起 cpu中断频率加快,开发浏览器的小伙伴们怕cpu吃不消,所以做了切换时间频率最小限制。什么是中断,可以查书自己。中断分为软中断,和硬中断。。。)
意味着你把setTimeout的时间设置为趋近于0,那么它的实际间隔时间还是会为最低的4ms ,或者16ms。
问题二,那么是不是网页重绘,屏幕就一定会重刷呢?
因为就算你网页重绘了,依然看不到,显示器还没有重新刷屏呢!
我们通过 requestAnimationFrame 告诉浏览器我们有业务方法需要像动画一样被不停调用,至于何时调用,浏览器做为一个客户端应用,我觉得应该能访问到系统的屏幕刷新频率,那么在系统重刷屏的时候,即浏览器知道,或者说有记录,那么浏览器就去调用requestAnimationFrame注册的业务方法。
我们在业务方法里面写动画业务。这样,我们的网页重绘就不浪费了。
兼容性:
ie 10.0,11.0
ff 22.0 (moz) 23.0 以上
chrome 28.0 以上
Safari 6.0 (webkit) 7.0 以上
Opera 16.0 以上
ios Safari 6.0-6.1 (webkit) 7.0 以上
android 不支持
ie mobile 10.0
以下是一个比较兼容的js版本
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
或者
window.requestAnimFrame = (function(w, r) {
w['r'+r] = w['r'+r] || w['webkitR'+r] || w['mozR'+r] || w['msR'+r] || w['oR'+r] || function(c){ w.setTimeout(c, 1000 / 60); };
return w['r'+r];
})(window, 'equestAnimationFrame');
另外:CSS3 transition或animation 绘制原理差不多,但是,css3在改变滚动条等就力不从心了。
参考文章:
http://www.zhangxinxu.com/wordpress/?p=3695
http://html5online.com.cn/articles/2012081102.html
http://www.cnblogs.com/aaronjs/archive/2012/07/05/2577177.html