动画性能优化-requestanimationframe、GPU等

  最近在做一个场景动画,有一个欢迎界面和一个主动画界面,两个界面之间的连接通过一个进度条来完成,当进度条完成,提供通往主动画的按钮。

  画面会从一个个的场景移动过去,用户可通过点击抽奖、查看气泡商铺等进行交互,同时可拖动画面,前移或后退。该项目中,出了主动画,还有人物场景对话的动画等,性能的优化、用户的体验变得尤为重要,这里总结一下在开发过程中使用的一些性能、体验优化方法。

1、动画
  a、优先采用requestanimationframe,实现动画帧的并发渲染;
  b、做减法:兼容低版本浏览器(a中的元素不生效,通过setTimeout实现动画),保留主动画性能,去除重要性不大的动画(跑马灯、过程小动画等);
  c、大图动画性能消耗非常大,使用translate3d实现GPU加速,动画结束、暂停时,切换回2d,取消加速;
  d、按需加载/卸载动画;

  e、每个动画帧处理函数简化,尽量减少或者去除回流、重绘。

2、加载、用户体验优化
  a、首屏优先加载,保证用户体验的流畅性:优先欢迎界面(即首屏)图片资源的加载,所有图片loaded以后,再启动主动画资源的加载,与进度条动画;
  b、资源的预加载:在进入主动画之前,进行主动画各资源的加载,当完成加载时,再promise结束进度条动画;

  c、常规优化:雪碧图、压缩、base64等;

  d、存储dom变量,减少dom tree的查找等;

  e、限频。

3、说明

  3.1、requestAnimationFrame  

    它是一种高级的方法,存在兼容性问题。主要原理是浏览器并行的渲染n个requestAnimationFrame,而且这种渲染是在浏览器自身渲染的同时发生,非常节省性能。相对setTimeout,是一个js的执行栈,只能串行执行,并且会影响其他js的处理。所以,使用前者,性能更佳,更流畅,交互体验更佳。特别是多个动画同时进行时,前者毫无压力,后者表示卡顿厉害。兼容代码如下,引自张鑫旭的log,感兴趣的同学可以仔细读一下:链接

    

 1 /* requestAnimationFrame.js
 2  * by zhangxinxu 2013-09-30
 3 */
 4 (function() {
 5     var lastTime = 0;
 6     var vendors = [‘webkit‘, ‘moz‘];
 7     for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
 8         window.requestAnimationFrame = window[vendors[x] + ‘RequestAnimationFrame‘];
 9         window.cancelAnimationFrame = window[vendors[x] + ‘CancelAnimationFrame‘] ||    // name has changed in Webkit
10                                       window[vendors[x] + ‘CancelRequestAnimationFrame‘];
11     }
12
13     if (!window.requestAnimationFrame) {
14         window.requestAnimationFrame = function(callback) {
15             var currTime = new Date().getTime();
16             var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
17             var id = window.setTimeout(function() {
18                 callback(currTime + timeToCall);
19             }, timeToCall);
20             lastTime = currTime + timeToCall;
21             return id;
22         };
23     }
24     if (!window.cancelAnimationFrame) {
25         window.cancelAnimationFrame = function(id) {
26             clearTimeout(id);
27         };
28     }
29 }());

  3.2、项目中的减法

    这种要做减法的情况下,最佳的体验是自己把动画都完成好,直接演示给产品、设计童鞋看,他们就能从中取舍了,没有任何的扯皮、分歧。tips:当然动画不需要跟实际用的一致,几个特性差不多就好,比如主动画背景图非常大,多个动画并行,且持续时间比较长。

  3.3、关于大图动画

    这种动画渲染的性能消耗往往非常大,考虑开启GPU来加速图层的渲染,但是由于GPU的渲染又是非常耗费内存、电量的,所以在不需要移动的情况下,需要关闭GPU,防止浏览器的崩溃。在该项目中,当用户进行游戏交互等,触发主动画暂停时,将通过设置translate2d,取消加速;启动时,再开启。

  

  3.4、按需加载/卸载动画

    对于场景动画来说,有些动效,只有出现在视口时,才有播放的必要性;离开视口,就可以关闭。通过判断动画当前的位置,可以实现动画的按需加载。

  3.5、重绘、回流

    动画帧内减少处理,即避免长时间的js执行;减少回流、重绘在哪里都适用,可以用transform等操作,来替代position;left等等的操作。当需要display:none的情况下(回流),使用opacity:0(重绘);或者visibility:hidden(重绘),将更优。回流的性能消耗要远大于重绘。

  

  3.6、首屏优先加载

    在网速很可观的情况下,完全可以同时加载整站的资源,仅将首屏的资源前置即可。

    但在网络状况很抓狂的情况下(如3g下),这种大量图片、音频的页面,就需要考虑资源分批启动加载的必要性了。在网速欠佳,但是服务器允许多并发的情况下,同时可以请求多个资源,此时带宽及其有限的,虽然整体的加载时间没变化,但是首屏的加载时间却延长了。如当前带宽时750kb/s,10个资源一起请求,则每个分到75kb/s,150kb的图片,需要加载2s;如果只有3个资源一起请求,分到250kb/s,需加载0.6s。因此,为了体验更佳,首屏的资源加载完毕,再开启主动画资源加载。

    

  3.7、资源的预加载

    因为主动画中的交互、资源较多,需要资源稳定以后才能有更好的用户体验,所以这里提供了资源的预加载。

    图片预加载:

newImgObjs[i] = new Image();
newImgObjs[i].src = animationImgs[i];

newImgObjs[i].onload = function() {
    loadeds++;
    if (loadeds == newImgObjs.length) {
        self.barObj.completeWelcomePromise.resolve();
        console.log(‘图片资源已经加载完成‘);
     }
};

newImgObjs[i].onerror = function() {
    loadeds++;
    if (loadeds == newImgObjs.length) {
        self.barObj.completeWelcomePromise.resolve();
        console.log(‘图片资源已经加载完成‘);
    }
};    

      音频预加载:

$audio[0].src = imgPath;
$audio.on(‘canplaythrough‘, function() {
    loadeds++;
    if (loadeds == (newImgObjs.length + 1)) {
        self.barObj.completePromise.resolve();
        console.log(‘音频资源已经加载完成‘);
    }
});

$audio[0].onerror = function(e) {
    loadeds++;
    if (loadeds == (newImgObjs.length + 1)) {
        self.barObj.completePromise.resolve();
        console.log(‘音频资源已经加载完成‘);
    }
};

  3.8、其他几种

    限频、dom操作、雪碧图等不再多说。关于响应式下的雪碧图处理,上一篇博客有提供系统的解决方案。

  3.9、promise的使用  

    在该项目中,promise的使用较为频繁,包括ajax请求、图片的预加载、进度条的处理等。

    

// 资源处理:预加载、监控加载完成、渲染
$.when(self.cmsInfoPromise, self.goodsInfoPromise, self.barObj.completeWelcomePromise)
    .done(function() {
        // 进度条动效
        self.barAnimation();
        self.handleResource();
        self.renderStores();
     });    
时间: 2024-12-18 10:55:53

动画性能优化-requestanimationframe、GPU等的相关文章

WEB 移动端 CSS3动画性能 优化

很多时候,我们在开发移动端的时候要使自己的网页兼容不同的机型,很多时候会采用CSS3动画,但是很多时候在安卓机下,动画明显会出现卡顿,很难看,那么这里我介绍几个CSS 属性进行硬件加速那么就会得到明显的效果: opacity: 1; -webkit-backface-visibility: hidden; -webkit-transform:translate3d(0,0,0); 这三个属性选其中一个放在要使用动画的元素中即可,很多时候你使用了-webkit-transform: 这个属性做了其

前端性能优化(css动画篇)

正巧看到在送书,于是乎找了找自己博客上记录过的一些东西来及其无耻的蹭书了~~~ 小广告:更多内容可以看我的博客 最近拜读了一下html5rocks上几位大神写的一篇关于CSS3动画性能优化的文章,学到了很多,在这里记录一下,其中的知识都是来源于这俩篇文章,我只是截取了其中比较关注的内容出来,原文地址High Performance Animations及Accelerated Rendering in Chrome 原理 现代浏览器在使用CSS3动画时,以下四种情形绘制的效率较高,分别是:* 改

前端性能优化 CSS动画

最近拜读了一下html5rocks上几位大神写的一篇关于CSS3动画性能优化的文章,学到了很多,在这里记录一下,其中的知识都是来源于这俩篇文章,我只是截取了其中比较关注的内容出来,原文地址High Performance Animations及Accelerated Rendering in Chrome 原理 现代浏览器在使用CSS3动画时,以下四种情形绘制的效率较高,分别是: * 改变位置 * 改变大小 * 旋转 * 改变透明度 层?重绘?回流和重布局?图层重组? 首先要了解CSS的图层的概

[iOS Animation]-CALayer 性能优化

性能优化 代码应该运行的尽量快,而不是更快 - 理查德 在第一和第二部分,我们了解了Core Animation提供的关于绘制和动画的一些特性.Core Animation功能和性能都非常强大,但如果你对背后的原理不清楚的话也会降低效率.让它达到最优的状态是一门艺术.在这章中,我们将探究一些动画运行慢的原因,以及如何去修复这些问题. CPU VS GPU 关于绘图和动画有两种处理的方式:CPU(中央处理器)和GPU(图形处理器).在现代iOS设备中,都有可以运行不同软件的可编程芯片,但是由于历史

vue-小爱ADMIN系列文章(二):微信微博等分享,国际化,前端性能优化,nginx服务器部署

最近在做我的小爱ADMIN后台管理系统,结合当前市场后台管理系统对相关功能的需求,我又开始新增了一些新的功能和组件,如分享功能组件,项目国际化功能:项目完成后,部署在nginx服务器,发现首次访问的速度特别慢,严重的影响了用户体验,因此,我又开始进行了一系列的前端性能优化;以及将优化后的项目部署到nginx服务器二级子目录的注意细节. 效果演示地址 github地址 分享功能 背景说明 用微信,微博等做网站的第三方登录及用微信和支付宝进行支付,都需要注册开发者账号和添加网站应用,比较麻烦.另外,

css写作建议和性能优化小结

1.前言 还有几天就到国庆中秋了,快要放假了,先祝大家节日快乐!之前写过js的写作建议和技巧,那么今天就来聊聊css吧!说到css,每一个网页都离不开css,但是对于css,很多开发者的想法就是,css只要能用来布局,把效果图排出来就可以了,其它的细节或者优化,不需要怎么考虑.但是我觉得css可不只是把页面的布局完成就是完事的,还需要考虑很多细节有优化,更不会像大家想得那么简单,在学习当中,如果发现什么技巧或者优化的点,我也会学以致用!那么今天,就分享下我总结的css写作建议和性能优化的一些问题

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

本文转载,原文地址:http://www.cnblogs.com/2050/p/3871517.html 用js来实现动画,我们一般是借助setTimeout或setInterval这两个函数,css3动画出来后,我们又可以使用css3来实现动画了,而且性能和流畅度也得到了很大的提升.但是css3动画还是有不少局限性,比如不是所有属性都能参与动画.动画缓动效果太少.无法完全控制动画过程等等.所以有的时候我们还是不得不使用setTimeout或setInterval的方式来实现动画,可是setTi

性能更好的js动画实现方式&mdash;&mdash;requestAnimationFrame

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

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

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