移动前端工作的那些事---前端制作之动画效率问题简析

做移动前端的盆友应该都知道,动画特效方面,尤其兼容安卓系统,就和互联网端兼容IE6一样麻烦。好多效果不错的创意都因为不兼容安卓系统而夭折。归根到底还是因为安卓浏览器性能的问题。这里篇外话一下,安卓手机的硬件可以甩苹果一条街。但在浏览器上表现的则相反。现在安卓系统已经发展到android 4.X了.可分配给浏览器的内存还是少的可怜!貌似不足10%; 所以一些很流畅的动画效果在IOS上跑一点压力没有。但在android上跑卡的要命!希望android 5.0时可以多给点内存在浏览器上,尽量提升一下浏览器的性能比。

言归正传,在移动端动画效果上,使用css3动画要比jquery动画效率高的多。在安卓手机上表现尤其明显!所以移动端动画以css3动画为优先。

我们知道css3动画分为两大类: animation和transform,这两者根据实际项目需求来分别使用。前者为关键帧动画,后者为变换动画。关键帧动画多用于可循环动画。而变换动画多用于一次性动画。当然这也不是绝对的。两者是可以相互转换使用的。究竟这两者在移动端那个更省浏览器性能,我参考了大量的文档也没有得出什么结论来。总之个人认为差不多吧。关键还是代码写的是否合理。方法是否应用得当。

通过做这个实际项目的大量效果测试得出一些自己的观点。大家仅供参考。

第一,先说说transform:

比如有一个需求,我需要将一个整体元素从下至上移动到屏幕上,这里有很多办法来加以实现。举例:要想让一个元素动起来,我们需要给这个元素先加一个原始的动画样式;

#erjidiv{
position: absolute; 
width: 100%; 
heigth:600px;
top: 0px; 
left: 0px; 
background-color:#000; 
-webkit-transform:translateY(100%);  
-webkit-transition:-webkit-transform 0s 0s;
}

然后通过某些事件接口修改这个样式即可

$("#erjidiv").css({
     "-webkit-transform":"translateY(0%)",
     "-webkit-transition":"-webkit-transform 0.5s ease-out 1s",
 })

这样通过位移Y轴translateY的方式.延迟1s 由快变慢的方式完成了动画。

在互联网中运用的CSS3样式。大家很习惯都使用 "-webkit-transition":"all 0.5s ease-out 1s",
但在移动端为了性能问题不推荐这么做。all所包含的是所有属性。如果只是某一处只运用了该动画的话。那么没有什么太大的区别,至少肉眼看不出来。但如果在同一时间实行多处元素动画的话。使用all属性就会有卡顿现象。而只写改变某个属性的话则该现象基本可以杜绝了。尤其在安卓上表现明显。所以此处我只使用了-webkit-transform属性。

有童靴会问,我改变其top的坐标值不是一样可以移动嘛;比如这样:

#erjidiv{
position: absolute; 
width: 100%; 
heigth:600px;
top: -600px; 
left: 0px; 
background-color:#000; 
-webkit-transition:top 0s 0s;
}


$("#erjidiv").css({
     "top":"0px",
     "-webkit-transition":"top 0.5s ease-out 1s",
 })

是的,这样依然可以达到该效果。但这么做显然在动画效率上不高。我参考了一些文章,说这么做效果还不如jquery动画效率高。这点我没有拿jquery动画和这个比较过。但这个和前者比较过。确实从流畅度来讲不如前者。尤其是同一时间多个元素同时执行动画。另外,像top、left、width、height等这些css基础属性在移动端不到迫不得已的情况下还是少参与动画的好。真的是很影响动画效率。我们使用css3的-webkit-transition的方式来做动画。与其门当户对配合的也应该是css3的属性-webkit-transform,两者完美结合才能在最大程度上提升动画效果。降低浏览器内存损耗。

此外,有童靴很可能使用互联网做动画的方式来做移动端动画(以前我也这么干过……)比如一个元素在静止状态时,采用了样式A。当它:hover时采用样式B。这样就实现了动画。把这种制作动画的方式搬到移动端一样也是可以的。其原理无非是两个样式的切换。那么根据这个原理上面的需求还可以变成这样:

.style1{
position: absolute; 
width: 100%; 
heigth:600px;
top: 0px; 
left: 0px; 
background-color:#000; 
-webkit-transform:translateY(100%);  
-webkit-transition:-webkit-transform 0s 0s;
}


.style2{
position: absolute; 
width: 100%; 
heigth:600px;
top: 0px; 
left: 0px; 
background-color:#000; 
-webkit-transform:translateY(0%);  
-webkit-transition:-webkit-transform 0.5s ease-out 1s;
}

$("#erjidiv").removeClass("style1").addClass("style2");

第二,再说说animation:

严格意义上来讲。transform方式不算是动画。只能算是变换。而animation才是正宗的动画。使用animation方式做动画,我们不得不提到关键帧@-webkit-keyframes。通过对其起始状态和终点状态之间的过程设置来形成动画。关于关键帧动画的使用就不举例说明了。百度一下有很多。

animation动画我个人理解多用于循环动画的地方。在这种动画需求下使用效率是最高的。优点是可以任意添加动作状态。缺点个人认为是不易进行控制。最大的缺陷是使用js无法获取到关键帧里面的动画状态参数。我想动态的改变关键帧里的变化数值,但无法做到。这里面的值只能写死或是使用百分比来代替具体数值。在移动端各种适配的需求下。很难有太灵活的变化。不过好像有js插件可以写关键帧动画。但我由于时间问题,还没有这方
面的详细研究。如果哪位同仁有这方面的经验,可以赐教一二。

之所以说它不易控制是没有一个好的启动切入点。目前我所知的办法就是当我要启动一个关键帧动画的时候,我需要给这个元素临时添加一个样式。

这个样式里写入了引用关键帧动画的-webkit-animation-name:XXX,然后设置周期、播放次数、变化方式等等参数。比如:

.fangda {
-webkit-animation-name: fangda;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: ease-out;
-webkit-animation-iteration-count: infinite;
}

@-webkit-keyframes fangda {
  0% {-webkit-transform:scale(1,1)}
 50% {-webkit-transform:scale(1.2,1.2); }
100% {-webkit-transform:scale(1,1); }
}


$("#erjidiv").addClass("fangda");

这样当我给元素添加样式后,动画开始启动。这种方法其实又回到了刚才在谈到transform方式时的用到的第三种方法。当我一瞬间同时使用好几个关键帧动画时,使用这种添加的方式没有修改其样式的效率高。会造成一瞬间卡顿的现象。这个尤以在安卓系统手机上表现明显。但第一种方法可以使用JS修改其样式。而关键帧动画却修改不了。

后来为了提高性能。想到不如先把样式加上。但我先让其暂停。想让它运行的时候再使用,于是乎想到了关键帧动画里有animation-play-state这个属性来控制暂停和运行。测试后果然可以。测试系统(android4.0以上,IOS6以上)。通过对比这种控制暂停,然后再让其启动的方式比单一添加样式的效率高很多。

.fangda {
-webkit-animation-name: fangda;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: ease-out;
-webkit-animation-iteration-count: infinite;
-webkit-animation-play-state:paused;
}


@-webkit-keyframes fangda {
  0% {-webkit-transform:scale(1,1)}
 50% {-webkit-transform:scale(1.2,1.2); }
100% {-webkit-transform:scale(1,1); }
}

$("#erjidiv").css("-webkit-animation-play-state","running");//根据需求再启动

通过以上的修正可以大大提高css3动画在移动端浏览器上效果的提升。即便在安卓浏览器上也能有较好的体现。

最后,再说说其他方面的个人心得;考虑到移动端浏览器性能问题。尽量避免同时多个动画。关键帧动画不用时,要么暂停掉。要么直接删除样式。个人更倾向于后者。有时候为了提高流畅度。必要时还要打开其渲染3d功能。在全局样式中进行设置如下样式:

-webkit-transform-style:preserve-3d;
-webkit-backface-visibility:hidden;
-webkit-transform:translate3d(0,0,0)

另外,浏览器在加载过程中会有一个预存渲染功能(专业术语叫什么忘记了,个人命名的便于理解),就是当要触发某些动画样式的时候,最好浏览器事先有过渲染,这样在执行起来的时候就会更加流畅。(因为节省了渲染时间)这也就很好的解释了为什么采用添加的方式没有改变其样式效率高!不添加动画样式时。浏览器事先是没有渲染的。添加时它需要临时渲染再执行动画,这需要时间。而改变样式却是在浏览器事先已经渲染好了动画,只不过不执行或是在暂停状态。需要时就可以马上启动。所以正是因为有了这个预存渲染的功能。再采用合适的方式时,就能缩短浏览器渲染时间,减少卡顿现象的产生的可能!真正的做到了提高移动端浏览器css3动画的效率问题!

你可能感兴趣的:(移动前端工作的那些事---前端制作之动画效率问题简析)