HTML5优化Web动画——requestAnimationFrame
2017-01-17 17:46
344 查看
在页面中实现动画,我们有很多选择
可以使用CSS3的transition
CSS3中的animation配合keyframes规则
SVG中也可以使用SMIL-animation
最原始的方法就是我们利用JavaScript的setTimeout/setInterval来实现动画
不过现在我们又多了一种方法
requestAnimationFrame
它是以递归的形式来实现动画
既然它是专门用来作Web动画的,它就一定有它自己的优势
使用setTimeout/setInterval制作动画有以下缺点
不能保证ms的准确性(JavaScript单线程,可能造成阻塞)
没有优化调用动画的循环机制
没有考虑到绘制动画的最佳时机(只是简单的按一定时间调用循环)
相比之下,requestAnimationFrame有以下优点
动画更加流畅,经由浏览器优化(页面刷新前执行一次)
窗口未激活时,动画暂停,有效节省CPU开销
省电,对移动端很友好
都是window上的方法
所以我们可以直接使用
requestAnimationFrame()
参数是一个回调函数,在函数内部我们需要改变元素样式
并且需要手动执行回调
同样返回一个句柄
传入cancelAnimationFrame可以取消它
看一个例子
现在我们要使页面中的一个元素变宽
先来看看setInterval的实现
requestAnimationFrame实现的动画
可以发现我们requestAnimationFrame展现的动画非常的流畅
不过现在的浏览器已经支持的很好了
我们可以为它写个polyfill
如果这个浏览器真的什么都没有
那么它只能退化(fallback)使用setTimeout和clearTimeout了
上面只是一个简单的polyfill
不过大神写了更好的
还可以把各浏览器前缀进行统一
后来又有了更新
相关js可以戳这里
github原址
感兴趣的同学可以研究研究
==主页传送门==
可以使用CSS3的transition
CSS3中的animation配合keyframes规则
SVG中也可以使用SMIL-animation
最原始的方法就是我们利用JavaScript的setTimeout/setInterval来实现动画
不过现在我们又多了一种方法
requestAnimationFrame
优势
requestAnimationFrame的原理与使用方法与setTimeout/setInterval类似它是以递归的形式来实现动画
既然它是专门用来作Web动画的,它就一定有它自己的优势
使用setTimeout/setInterval制作动画有以下缺点
不能保证ms的准确性(JavaScript单线程,可能造成阻塞)
没有优化调用动画的循环机制
没有考虑到绘制动画的最佳时机(只是简单的按一定时间调用循环)
相比之下,requestAnimationFrame有以下优点
动画更加流畅,经由浏览器优化(页面刷新前执行一次)
窗口未激活时,动画暂停,有效节省CPU开销
省电,对移动端很友好
使用
requestAnimationFrame和setTimeout/setInterval一样都是window上的方法
所以我们可以直接使用
requestAnimationFrame()
参数是一个回调函数,在函数内部我们需要改变元素样式
并且需要手动执行回调
同样返回一个句柄
传入cancelAnimationFrame可以取消它
看一个例子
现在我们要使页面中的一个元素变宽
<div id="demo"></div>
#demo { width: 0; height: 100px; background-color: orange; }
先来看看setInterval的实现
var demo = document.getElementById('demo'); var len = 0; var timerFunc = function(){ len += 5; if(len <= 200){ demo.style.width = len + 'px'; }else{ clearInterval(timer); } } var timer = setInterval(timerFunc, 20);
requestAnimationFrame实现的动画
var demo = document.getElementById('demo'); var len = 0; var timerFunc = function(){ len += 5; if(len <= 200){ demo.style.width = len + 'px'; requestAnimationFrame(timerFunc); /*执行回调*/ }else{ cancelAnimationFrame(timer); } } var timer = requestAnimationFrame(timerFunc);
可以发现我们requestAnimationFrame展现的动画非常的流畅
兼容
既然是比较新的东西,难免就会存在各浏览器的兼容性问题不过现在的浏览器已经支持的很好了
我们可以为它写个polyfill
window.requestAnimationFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback){ window.setTimeout(callback, 1000 / 60); }; })(); window.requestAnimationFrame = (function(){ return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function(ID){ window.clearTimeout(ID); }; })();
如果这个浏览器真的什么都没有
那么它只能退化(fallback)使用setTimeout和clearTimeout了
上面只是一个简单的polyfill
不过大神写了更好的
还可以把各浏览器前缀进行统一
(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 - (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); }; }());
后来又有了更新
相关js可以戳这里
github原址
if (!Date.now) Date.now = function() { return new Date().getTime(); }; (function() { 'use strict'; var vendors = ['webkit', 'moz']; for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { var vp = vendors[i]; window.requestAnimationFrame = window[vp+'RequestAnimationFrame']; window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame'] || window[vp+'CancelRequestAnimationFrame']); } if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) // iOS6 is buggy || !window.requestAnimationFrame || !window.cancelAnimationFrame) { var lastTime = 0; window.requestAnimationFrame = function(callback) { var now = Date.now(); var nextTime = Math.max(lastTime + 16, now); return setTimeout(function() { callback(lastTime = nextTime); }, nextTime - now); }; window.cancelAnimationFrame = clearTimeout; } }());
感兴趣的同学可以研究研究
==主页传送门==
相关文章推荐
- HTML5探秘:用requestAnimationFrame优化Web动画
- HTML5探秘:用requestAnimationFrame优化Web动画
- html5[1]:优化Android Webview性能
- HTML5缓存机制浅析:移动端Web加载性能优化
- HTML5缓存机制浅析:移动端Web加载性能优化
- HTML5缓存机制浅析:移动端Web加载性能优化
- 提升html5的性能体验系列之五webview启动速度优化及事件顺序解析]
- HTML5缓存机制浅析:移动端Web加载性能优化(转)
- 争用、 性能下降和死锁进行 Web 服务请求 ASP.NET 应用程序优化
- Web站点优化
- Flickr 的开发者的 Web 应用优化技巧(转)
- 优化 Web 服务器计算机和特定应用程序的配置文件以符合您的特定需要
- IBM Rational助您轻松完成基于J2EE的Web应用系统的性能测试和性能优化(二)
- 上周技术关注:Flickr的开发者的Web应用优化技巧
- ASPX页Web服务调用性能优化
- 优化配置 如何改进Web站点的整体性能(转)
- 从MVC与三层架构谈到优化架构提高Web效率
- JBoss, Tomcat等WEB服务器的优化策略(二)
- ASPX页Web服务调用性能优化
- Web下的性能测试与优化