用js来实现动画,我们一般是借助setTimeout或setInterval这两个函数,css3动画出来后,我们又可以使用css3来实现动画了,而且性能和流畅度也得到了很大的提升。但是css3动画还是有不少局限性,比如不是所有属性都能参与动画、动画缓动效果太少、无法完全控制动画过程等等。所以有的时候我们还是不得不使用setTimeout或setInterval的方式来实现动画,可是setTimeout和setInterval有着严重的性能问题,虽然某些现代浏览器对这两函个数进行了一些优化,但还是无法跟css3的动画性能相提并论。这个时候,就该requestAnimationFrame出马了。

requestAnimationFrame 是专门为实现高性能的帧动画而设计的一个API,目前已在多个浏览器得到了支持,包括IE10+,Firefox,Chrome,Safari,Opera等,在移动设备上,ios6以上版本以及IE mobile 10以上也支持requestAnimationFrame,唯一比较遗憾的是目前安卓上的原生浏览器并不支持requestAnimationFrame,不过对requestAnimationFrame的支持应该是大势所趋了,安卓版本的chrome 16+也是支持requestAnimationFrame的。


requestAnimationFrame 比起 setTimeout、setInterval的优势主要有两点:

1、requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。

2、在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。


注意:

像setTimeout、setInterval一样,requestAnimationFrame是一个全局函数。调用requestAnimationFrame后,它会要求浏览器根据自己的频率进行一次重绘,它接收一个回调函数作为参数,在即将开始的浏览器重绘时,会调用这个函数,并会给这个函数传入调用回调函数时的时间作为参数。由于requestAnimationFrame的功效只是一次性的,所以若想达到动画效果,则必须连续不断的调用requestAnimationFrame,就像我们使用setTimeout来实现动画所做的那样。requestAnimationFrame函数会返回一个资源标识符,可以把它作为参数传入cancelAnimationFrame函数来取消requestAnimationFrame的回调。怎么样,是不是也跟setTimeout的clearTimeout很相似啊。

所以,可以这么说,requestAnimationFrame就是一个性能优化版、专为动画量身打造的setTimeout,不同的是requestAnimationFrame不是自己指定回调函数运行的时间,而是跟着浏览器内建的刷新频率来执行回调,这当然就能达到浏览器所能实现动画的最佳效果了。

目前,各个支持requestAnimationFrame的浏览器有些还是自己的私有实现,所以必须加前缀,对于不支持requestAnimationFrame的浏览器,我们只能使用setTimeout,因为两者的使用方式几近相同,所以这两者的兼容并不难。对于支持requestAnimationFrame的浏览器,我们使用requestAnimationFrame,而不支持的我们优雅降级使用传统的setTimeout。把它们封装一下,就能得到一个统一兼容各大浏览器的API了。

(function() {
var lastTime = 0;
var vendors = ['webkit', 'moz', 'ms', 'o'];
for( var x=0 ; x<vendors.length ; ++x){
if ( window.requestAnimationFrame && window.cancelAnimationFrame ) {
break;
}
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 - (currTime - lastTime));
var id = window.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if(!window.cancelAnimationFrame){
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}
}());

//简化版本

window.requestAnimationFrame=window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function( callback ){
//为了使setTimteout的尽可能的接近每秒60帧的效果
window.setTimeout(callback,1000/60);
} window.cancelAnimationFrame=window.cancelAnimationFrame ||
Window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.msCancelAnimationFrame ||
window.oCancelAnimationFrame ||
function( id ){
//为了使setTimteout的尽可能的接近每秒60帧的效果
window.clearTimeout( id );
}

下面举个简单的例子来说明怎么运用requestAnimationFrame进行动画,下面的代码会将id为demo的div以动画的形式向右移动到300px
<div id="demo" style="position:absolute; width:100px; height:100px; background:#ccc; left:0; top:0;"></div>
<script>
var demo = document.getElementById('demo');
function rander(){
demo.style.left = parseInt(demo.style.left) + 1 + 'px'; //每一帧向右移动1px
}
requestAnimationFrame(function(){
rander();
//当超过300px后才停止
if(parseInt(demo.style.left)<=300){
requestAnimationFrame(arguments.callee);
}
});
</script>

requestAnimationFrame/cancelAnimationFrame——性能更好的js动画实现方式的更多相关文章

  1. 性能更好的js动画实现方式——requestAnimationFrame

    用js来实现动画,我们一般是借助setTimeout或setInterval这两个函数,css3动画出来后,我们又可以使用css3来实现动画了,而且性能和流畅度也得到了很大的提升.但是css3动画还是 ...

  2. 性能更好的js动画实现方式——requestAnimationFrame

    本文转载,原文地址:http://www.cnblogs.com/2050/p/3871517.html 用js来实现动画,我们一般是借助setTimeout或setInterval这两个函数,css ...

  3. 性能更好的js动画实现方式---requestAnimationFrame

    用js来实现动画,我们一般是借助setTimeout或setInterval这两个函数,css3动画出来后,我们又可以使用css3来实现动画了,而且性能和流畅度也得到了很大的提升.但是css3动画还是 ...

  4. CSS VS JS动画,哪个更快[译]

    英文原文:https://davidwalsh.name/css-js-animation 原作者Julian Shapiro是Velocity.js的作者,Velocity.js是一个高效易用的js ...

  5. JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能

    摘要: 理解浏览器渲染. 原文:JavaScript是如何工作的: CSS 和 JS 动画底层原理及如何优化它们的性能 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这是专门探索 J ...

  6. 关于JS动画和CSS3动画的性能差异

    本文章为综合其它资料所得. 根据Google Developer,Chromium项目里,渲染线程分为main thread和compositor thread. 如果CSS动画只是改变transfo ...

  7. js动画最佳实现——requestAnimationFrame

    我们经常用setInterval来实现动画,其实这种做法不是太好,因为不同浏览器的刷新频率也不一样(一般认为设置16为最佳,按每秒60帧算,1000/60≍16.67) var dis = 0,tim ...

  8. How Javascript works (Javascript工作原理) (十三) CSS 和 JS 动画底层原理及如何优化其性能

    个人总结:读完这篇文章需要20分钟. 这是 JavaScript 工作原理的第十三章. 概述 正如你所知,动画在创建令人叹服的网络应用中扮演着一个关键角色.由于用户越来越注重用户体验,商户开始意识到完 ...

  9. JavaScript 工作原理之十三-CSS 和 JS 动画底层原理及如何优化其性能

    原文请查阅这里,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland. 本系列持续更新中,Github 地址请查阅这里. 这是 JavaScript 工作原理的第十三章. 概述 正如你 ...

随机推荐

  1. Numpy学习-(1)

    记录我学习Numpy过程 1. 介绍 (1)NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库 ...

  2. Matlab学习-(1)

    1. 认识Matlab (1)MATLAB是美国MathWorks公司出品的商业数学软件,用于算法开发.数据可视化.数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括MATLAB和Simul ...

  3. 3. JS生成32位随机数

    function randomWord ( randomFlag,min,max ) { var str = " ", range = min, arr = ['0','1','2 ...

  4. MySQL笔记总结-TCL语言

    TCL语言 事务 一.含义 事务控制语言 Transaction Control Language 事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行 二.特点(ACID ...

  5. .Net Core主机配置

    Host:(主机)负责web应用程序的启用和生成期管理,配置服务器和请求处理管道. 主机配置日志,依赖注入关系,实际上是一个封装了应用资源的对象. 创建主机生成器-〉配置主机-〉创建主机-〉运行主机. ...

  6. AJAX教程——检视阅读

    AJAX教程--检视阅读 参考 AJAX 教程--菜鸟 AJAX 教程--w3cschool AJAX 教程--w3school.cn AJAX 教程--易百 AJAX = Asynchronous ...

  7. 算法笔记刷题5(PAT A1025)

    第一次上手PAT的甲级题目,瑟瑟发抖(英语不好对着题目愣了半天) 这一题的要点是使用sort函数. 使用sort函数必须使用 #include <algorithm> using name ...

  8. [Linux] 检查是否已有进程在运行

    出处:sblim-sfcb-1.4.9 / sfcBroker.c int process_is_running() { #define STRBUF_LEN 512 #define BUF_LEN ...

  9. java 8 Streams简介

    目录 简介 Functional Interface Function:一个参数一个返回值 BiFunction:接收两个参数,一个返回值 Supplier:无参的Function Consumer: ...

  10. 【kafka KSQL】游戏日志统计分析(1)

    [kafka KSQL]游戏日志统计分析(1) 以游戏结算日志为例,展示利用KSQL对日志进行统计分析的过程. 启动confluent cd ~/Documents/install/confluent ...