移動前端工作的那些事---前端制作之動畫效率問題簡析


動畫特效方面,尤其兼容安卓系統,就和互聯網端兼容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");
 
這樣,通過移除和添加樣式也可以實現上面的需求。那么這種辦法是不是效率也比較高呢?
通過實際測試,當多個元素同時動畫的時候。使用修改其樣式也就是第一種辦法要比這種添加和刪除樣式高效的多。所以,如果使用-webkit- transform這種動畫方式的時候,最好的方案就是第一種,使用js修改其動畫樣式的效率是最高的。其他的方法效率都不高。不推薦在移動端上使用。
 
 
第二,再說說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動畫的效率問題!
 
 
原文:http://blog.sina.com.cn/s/blog_3f1fc8950102v0un.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM