文章已同步至个人Blog:Benjamin-专注前端开发和用户体验
相关概念:绘制频率、屏幕刷新频率、硬件加速、60fps
绘制频率:
页面上每一帧变化都是系统绘制出来的(GPU或者CPU)【参考浏览器渲染原理】。但这种绘制又和PC游戏的绘制不同,它的最高绘制频率受限于显示器的刷新频率(而非显卡),所以大多数情况下最高的绘制频率只能是每秒60帧(frame per second,以下用fps简称),对应于显示器的60Hz。60fps是一个最理想的状态,在日常对页面性能的测试中,60fps也是一个重要的指标,the closer the better。
刷新频率: 图像在屏幕上更新的速度,也即屏幕上的图像每秒钟出现的次数,它的单位是赫兹(Hz)。刷新频率越高,屏幕上图像闪烁感就越小,稳定性也就越高,换言之对视力的保护也越好。一般人的眼睛、不容易察觉75Hz以上刷新频率带来的闪烁感,因此最好能将您显示卡刷新频率调到75Hz以上。要注意的是,并不是所有的显示卡都能够在最大分辨率下达到70Hz以上的刷新频率(这个性能取决于显示卡上RAMDAC的速度),而且显示器也可能因为带宽不够而不能达到要求。影响刷新率最主要的还是显示器的带宽。
显示器带宽是显示器视频放大器通频带宽度的简称,指电子枪每秒钟在屏幕上扫过的最大总像素数,以MHz(兆赫兹)为单位。 带宽的值越大,显示器性能越好。
硬件加速: 硬件有三个处理器,CPU、GPU和APU(不是加速处理器是声音处理器)。他们通过PCI/AGP/PCIE总线交换数据。今天,GPU已经不再局限于3D图形处理了,GPU通用计算技术发展已经引起业界不少的关注,事实也证明在浮点运算、并行计算等部分计算方面,GPU可以提供数十倍乃至于上百倍于CPU的性能。
60Hz和60fps是什么关系
没有任何关系。fps代表GPU渲染画面的频率,Hz代表显示器刷新屏幕的频率。一幅静态图片,你可以说这副图片的fps是0帧/秒,但绝对不能说此时屏幕的刷新率是0Hz,也就是说刷新率不随图像内容的变化而变化。游戏也好浏览器也好,我们谈到掉帧,是指GPU渲染画面频率降低。比如跌落到30fps甚至20fps,但因为视觉暂留原理,我们看到的画面仍然是运动和连贯的。
PS: 以下示例在Chrome环境中运行
实例:
<style type="text/css">.animate {width: 200px;height: 200px;margin: 0 auto;border-radius: 50%;background-color: #f00;line-height: 200px;border-radius: 50%;text-align: center;color: #fff;font-size: 20px;}.animate-transition {transition : transform 2s linear;-moz-transition : -moz-transform 2s linear;-webkit-transition : -webkit-transform 2s linear;-o-transition : -o-transform 2s linear;}.animate-transition:hover {cursor: pointer;transform : rotate(360deg);-moz-transform : rotate(360deg);-webkit-transform : rotate(360deg);-o-transform : rotate(360deg);}</style><div class="animate animate-transition">Transition Animation</div>
查看实例演示
Keyframes animation通过定义多个关键帧以及定义每个关键帧中的元素的属性值来实现更为复杂的动画效果。 实例:
<style type="text/css">.animate-keyframes {-webkit-animation: frames 2s linear infinite;}.animate-keyframes:hover {cursor: pointer;-webkit-animation: none;}@-webkit-keyframes frames {0% {background-color: #f00;-webkit-transform: rotate(0deg);}100% {background-color: #f00;-webkit-transform: rotate(360deg);}}</style><div class="animate animate-keyframes">keyframes animation</div>
查看实例演示
优点: 简单、高效 声明式的 不依赖与主线程,采用硬件加速(GPU) 简单的控制keyframe animation 播放和暂停 缺点: 不能动态的修改或定义动画内容 不同的动画无法实现同步 多个动画彼此无法堆叠 另: 1) CSS3 transition强制硬件加速会加大GPU消耗,高负荷情形下将导致运行不流畅。这种情况在移动设备上尤为明显。(特殊情况下,比如当数据在浏览器主线程和排版线程之间传递产生的瓶颈也会导致不流畅)。某些CSS属性,比如transform和opacity,则不受这些瓶颈影响。Adobe在这里精心总结了这些问题。详细请戳 transition的兼容性问题是个诟病,IE10+及现代浏览器,使用起来会造成很多不便。 由于transition并不是由javaScript原生控制(而仅仅是由Javascript触发),浏览器无法获知如何与控制这些transition的JavaScript代码同步地优化他们。 2) keyframes animation 的动画曲线会应用到所有变化的属性上,而且手写比较复杂的动画,写起来就是噩梦。
<div class="animate-svg"><svg id="svgAnimation" ns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200"><g transform="translate(100,100)"><g><rect width="200" height="200" rx="100" ry="100" fill="red" transform="translate(-100,-100)"></rect><text x="-60" y="-0" font-size="20" fill="white" >SVG Animation</text><!-- Add ease-in-out and infinite iterations to this animation and the code --><animateTransform attributeName="transform" attributeType="xml" type="rotate" from="0" to="360" dur="3s" repeatCount="indefinite">SVG Animation</animateTransform></g></g></svg></div>
查看实例演示
优点:
1) 矢量图形,不受像素影响——SVG的这个特性使得它在不同的平台或者媒体下表现良好,无论屏幕分辨率如何
2) SVG对动画的支持较好,其DOM结构可以被其特定语法或者Javascript控制,从而轻松的实现动画
3) Javascript可以完全控制SVG Dom 元素
4) SVG的结构是XML,其可访问性(盲文、声音朗读等)、可操作性、可编程性、可被CSS样式化完胜Canvas。另外,其支持 ARIA 属性,使其如虎添翼。
缺点:
1) DOM比正常的图形慢,而且如果其结点多而杂,就更慢。
2) SVG 画点报表什么的,还行;在网页游戏前,就束手无策了;当然可以结合 Canvas + SVG实现。
3) 不能动态的修改动画内容
4) 不能与HTML内容集成
5) 整个SVG作为一个动画
6) 浏览器兼容性问题,IE8-以及Android 2.3默认浏览器是不支持SVG
jQuery动画使用setInterval实现:
// 用例$("#div").animate({});// 源码jQuery.fx.timer = function( timer ) {if ( timer() && jQuery.timers.push( timer ) && !timerId ) {timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );}};jQuery.fx.interval = 13;
jQuery的动画帧宽为什么是13ms呢
How to determine the best “framerate” (setInterval delay) to use in a JavaScript animation loop?
为什么jQuery用setInterval而不用RAF?
优点: 易用,低效,兼容好;
缺点:
1) setInterval多个间隔可能会被跳过
2) setInterval多个间隔可能比预期小
3) 不同浏览器的精度量级不同:
4) jQuery 无法解决频繁触发 Layout 导致的抽动。
实例:
<style type="text/css">.animate-RAF {}.animate-input {margin-top: 10px;text-align: center;}</style><div id="animate-RAF" class="animate animate-RAF">RAF Animation</div><div class="animate-input"><input type="button" id="btn_start" value="Start" style="width:100px;height:30px"></div><script type="text/javascript">var animate_raf = document.getElementById("animate-RAF"),btn_start = document.getElementById("btn_start"),frameid = null;function frame(time) {animate_raf.style['-webkit-transform'] = 'rotate('+ Math.cos(time/1000)*360 +'deg)';frameid = requestAnimationFrame(frame);}// bind Eventbtn_start.addEventListener("click", function(event) {var val = this.value;if(val === "Start") {frameid = requestAnimationFrame(frame);this.value = "Pause";}else {this.value = "Start";cancelAnimationFrame(frameid);}}, false);</script>
查看实例演示
优点:
1) 在每次浏览器更新页面时,能获取通知并执行应用。 简单理解为,RAF能在每个16.7ms间执行一次咱们的函数,不多不少。
2) 最小化的消耗资源,RAF在页面被切换或浏览器最小化时,会暂停执行,等页面再次关注时,继续执行动画。
3) 相比 CSS 动画有更好的掌控,能合理降低CPU的使用。
缺点:
1) 无法控制执行时间,执行时间由系统根据屏幕刷新时间决定
2) 浏览器兼容性问题,IE10+及现代浏览器,低版本浏览器建议降级处理,使用setInterval或setTimeout
优点:
1) 画2D图形时,页面渲染性能比较高
2) 页面渲染性能受图形复杂度影响小
3) 渲染性能只受图形的分辨率的影响
4) 画出来的图形可以直接保存为 .png 或者 .jpg的图形
5) 最适合于画光栅图像(如游戏和不规则几何图形等),编辑图片还有其他基于像素的图形操作。
缺点:
1) 整个就是一张图,无论你往上画什么东西——没有DOM 结点可供操作
2) 没有实现动画的API,你必须依靠定时器和其他事件来更新Canvas
3) 对文本的渲染支持是比较差
4) 对要求有高可访问性(盲文、声音朗读等)页面,比较困难
5) 对交互要求高的(比如TIBCO的很多产品)的界面,不建议使用Canvas
WebGL是一种3D绘图标准,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。
浏览器支持:
Internet Explorer 11+
Google Chrome 9+
Firefox 4+
Opera 12+
Safari 5.1+
1) 不同的api有不同的模型动画
2) 不必要的维护来支持多种方式实现同样的事情
3) Web开发人员需要学习多种实现技术
4) Javascript不容易设置声明式动画
1)W3Web Animations 1.0
2)JavaScript implementation of the Web Animations API
Web Animations API为CSS和SVG动画提供了单一接口。旨在通过提供更好的性能、更好的控制时间线和播放、灵活、统一的Javascript编程接口,使做一些事情更容易。
当前状态:
Specification at First Public Working Draft: www.w3.org/TR/web-animations
Chrome: CSS Transitions & Animations rewritten on top of the Web Animations model JavaScript API in development behind a flag
Firefox & Safari: Started implementation
IE: No public signals
实例一:A simple example
var web_animation_1 = document.getElementById("web_animation_1");web_animation_1.addEventListener('click', function() {web_animation_1.animate([{transform: 'rotate(0deg)'}, {transform: 'rotate(360deg)'}],{duration: 2});}, false);
查看实例演示
实例二:More complex timing
var web_animation_2 = document.getElementById("web_animation_2");web_animation_2.addEventListener('click', function()
新闻热点
疑难解答