容易被忽视的RequestAnimationFrame

传统的JS动画都是用 setTimeout 和 setInterval 实现的,后来无意中在网上看到一个新的JS函数 requestAnimationFrame 用它来替代传统的JS动画方法,说是效果更好,当时也没有仔细深究。直到昨天去魅族面试的时候,面试官问我有什么新的办法可以替代传统的JS动画,我说“我知道一个叫 requestAnimationFrame 的函数,它的执行效果更好”。但是让我仔细描述的时候,我就说不下去了,这也是我写这篇博客的初衷,我们学习的过程中一定要知其然比知其所以然,不要什么都略懂,最后落得跟半吊子一样。

定时器一直都是JS动画的核心技术。而编写动画循环的关键是要知道延迟时间多长合适。一方面,循环间隔必须足够短,这样才能让不同的动画效果显得平滑流畅;另一方面,循环间隔还要足够长,才能确保浏览器有能力渲染产生的变化。

大多数电脑显示器的刷新频率是60HZ,也就是每秒钟重绘60次。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过那个频率用户体验也不会提升。因此,最平滑动画的最佳循环间隔是 1000ms / 60 ,约为16.7ms。

传统的 setTimeout 和 setInterval 它们都不是很精确,因为它们实际上只是把动画代码添加到浏览器UI线程队尾以等待执行时间,如果它们前面有其它任务,则必须等前面的任务执行完在执行动画代码。

而 requestAnimationFrame 采用系统时间间隔,让各种动画效果能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。它有如下三个特点:

  • 会把每一帧中所有的DOM操作集中起来,在一次动画操作就完成,并且动画的时间间隔紧紧跟随浏览器的刷新频率(不需要设置时间间隔)。
  • 在隐藏或者不可见的元素中,不会进行动画操作。
  • 当浏览器不是激活状态,不会进行动画操作。

下面是一个兼容所有浏览器的使用 requestAnimationFrame 的代码(IE9-无该方法)

(function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; x++) {
        window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
    }
    if (!window.requestAnimationFrame) {
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
            var id = setTimeout(function() {
                callback(currTime + timeToCall);
            }, timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        }
    }
    if (!window.cancelAnimationFrame) {
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        }
    }
}());

最后附上我利用 requestAnimationFrame 制作的一个 跳动的小球 的DEMO。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一:在制作一个Web应用或Web站点的过程中,你是如何考虑他的UI、安全性、高性能、SEO、可维护性以及技术因素的...
    Arno_z阅读 1,277评论 0 1
  • requestAnimationFrame这个API,可能很多人都听过,但并没有真正用过。MDN上的解释是: wi...
    Perkin_阅读 3,592评论 0 4
  • 看了很多视频、文章,最后却通通忘记了,别人的知识依旧是别人的,自己却什么都没获得。此系列文章旨在加深自己的印象,因...
    DCbryant阅读 765评论 0 2
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,301评论 4 61
  • 晚上,许林一陪着翩翩打点滴。翩翩的高烧退了,精神略微恢复的她不再老老实实地坐在座位上,她在自己的活动范围内释放着还...
    梅花猫阅读 536评论 1 2