好文章,很有幫助,謝謝啦,頂一下
移動前端工作的那些事---前端製作之動畫效率問題簡析
最近工作很忙,好久沒有更新部落格內容了。前些日子跳槽到一家新單位就接到了乙個很難的工作專案。在這個專案中技術核心點是動畫效率問題。經過了近半個月的攻關各種難題總算是搞定了。同時,對移動端瀏覽器對動畫的解析能力有了乙個更高的認知。在這裡想和大家分享一下。有不足之處歡迎指正!
做移動前端的盆友應該都知道,動畫特效方面,尤其相容安卓系統,就和網際網路端相容ie6一樣麻煩。好多效果不錯的創意都因為不相容安卓系統而夭折。歸根到底還是因為安卓瀏覽器效能的問題。這裡篇外話一下,安卓手機的硬體可以甩蘋果一條街。但在瀏覽器上表現的則相反。現在安卓系統已經發展到android 4.x了.可分配給瀏覽器的記憶體還是少的可憐!貌似不足10%; 所以一些很流暢的動畫效果在ios上跑一點壓力沒有。但在android上跑卡的要命!希望android 5.0時可以多給點內存在瀏覽器上,盡量提公升一下瀏覽器的效能比。
言歸正傳,在移動端動畫效果上,使用css3動畫要比jquery動畫效率高的多。在安卓手機上表現尤其明顯!所以移動端動畫以css3動畫為優先。
我們知道css3動畫分為兩大類: animation和transform,這兩者根據實際專案需求來分別使用。前者為關鍵幀動畫,後者為變換動畫。關鍵幀動畫多用於可迴圈動畫。而變換動畫多用於一次性動畫。當然這也不是絕對的。兩者是可以相互轉換使用的。究竟這兩者在移動端那個更省瀏覽器效能,我參考了大量的文件也沒有得出什麼結論來。總之個人認為差不多吧。關鍵還是**寫的是否合理。方法是否應用得當。
第一,先說說transform:
比如有乙個需求,我需要將乙個整體元素從下至上移動到螢幕上,這裡有很多辦法來加以實現。舉例:要想讓乙個元素動起來,我們需要給這個元素先加乙個原始的動畫樣式;
#erjidiv
然後通過某些事件介面修改這個樣式即可
$("#erjidiv").css()
這樣通過位移y軸translatey的方式.延遲1s 由快變慢的方式完成了動畫。
在網際網路中運用的css3樣式。大家很習慣都使用 "-webkit-transition":"all 0.5s ease-out 1s",
但在移動端為了效能問題不推薦這麼做。all所包含的是所有屬性。如果只是某一處只運用了該動畫的話。那麼沒有什麼太大的區別,至少肉眼看不出來。但如果在同一時間實行多處元素動畫的話。使用all屬性就會有卡頓現象。而只寫改變某個屬性的話則該現象基本可以杜絕了。尤其在安卓上表現明顯。所以此處我只使用了-webkit-transform屬性。
有童靴會問,我改變其top的座標值不是一樣可以移動嘛;比如這樣:
#erjidiv
$("#erjidiv").css()
是的,這樣依然可以達到該效果。但這麼做顯然在動畫效率上不高。我參考了一些文章,說這麼做效果還不如jquery動畫效率高。這點我沒有拿jquery動畫和這個比較過。但這個和前者比較過。確實從流暢度來講不如前者。尤其是同一時間多個元素同時執行動畫。另外,像top、left、width、height等這些css基礎屬性在移動端不到迫不得已的情況下還是少參與動畫的好。真的是很影響動畫效率。我們使用css3的-webkit-transition的方式來做動畫。與其門當戶對配合的也應該是css3的屬性-webkit-transform,兩者完美結合才能在最大程度上提公升動畫效果。降低瀏覽器記憶體損耗。
此外,有童靴很可能使用網際網路做動畫的方式來做移動端動畫(以前我也這麼幹過……)比如乙個元素在靜止狀態時,採用了樣式a。當它:hover時採用樣式b。這樣就實現了動畫。把這種製作動畫的方式搬到移動端一樣也是可以的。其原理無非是兩個樣式的切換。那麼根據這個原理上面的需求還可以變成這樣:
.style1
.style2
$("#erjidiv").removeclass("style1").addclass("style2");
這樣,通過移除和新增樣式也可以實現上面的需求。那麼這種辦法是不是效率也比較高呢?
通過實際測試,當多個元素同時動畫的時候。使用修改其樣式也就是第一種辦法要比這種新增和刪除樣式高效的多。所以,如果使用-webkit-transform這種動畫方式的時候,最好的方案就是第一種,使用js修改其動畫樣式的效率是最高的。其他的方法效率都不高。不推薦在移動端上使用。
第二,再說說animation:
animation動畫我個人理解多用於迴圈動畫的地方。在這種動畫需求下使用效率是最高的。優點是可以任意新增動作狀態。缺點個人認為是不易進行控制。最大的缺陷是使用js無法獲取到關鍵幀裡面的動畫狀態引數。我想動態的改變關鍵幀裡的變化數值,但無法做到。這裡面的值只能寫死或是使用百分比來代替具體數值。在移動端各種適配的需求下。很難有太靈活的變化。不過好像有js外掛程式可以寫關鍵幀動畫。但我由於時間問題,還沒有這方
面的詳細研究。如果哪位同仁有這方面的經驗,可以賜教一二。
之所以說它不易控制是沒有乙個好的啟動切入點。目前我所知的辦法就是當我要啟動乙個關鍵幀動畫的時候,我需要給這個元素臨時新增乙個樣式。
.fangda
@-webkit-keyframes fangda
50%
100%
}$("#erjidiv").addclass("fangda");
這樣當我給元素新增樣式後,動畫開始啟動。這種方法其實又回到了剛才在談到transform方式時的用到的第三種方法。當我一瞬間同時使用好幾個關鍵幀動畫時,使用這種新增的方式沒有修改其樣式的效率高。會造成一瞬間卡頓的現象。這個尤以在安卓系統手機上表現明顯。但第一種方法可以使用js修改其樣式。而關鍵幀動畫卻修改不了。
後來為了提高效能。想到不如先把樣式加上。但我先讓其暫停。想讓它執行的時候再使用,於是乎想到了關鍵幀動畫裡有animation-play-state這個屬性來控制暫停和執行。測試後果然可以。測試系統(android4.0以上,ios6以上)。通過對比這種控制暫停,然後再讓其啟動的方式比單一新增樣式的效率高很多。
.fangda
@-webkit-keyframes fangda
50%
100%
}$("#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動畫的效率問題!
移動前端viewPort的那些事
1 viewport簡單說 一般來說,移動上的viewport都是大於瀏覽器視窗的,不同的裝置有自己預設的viewport值 980px或1024px 2 三個viewport的理解 layout viewport visual viewport idea viewport 上面說的,預設的view...
移動開發的那些痛
這篇文章不定期更新,總結在移動開發中至少困擾我一天以上的問題。1.聯網 中國這個土鱉的網路環境下,我都不知道wap是怎麼產生的,我只知道,很多很多手機都預設支援wap。大部分j2me書本上,是絕對不會介紹 連線的。在這方面,我走了不少彎路。首先給出標準的模式 如果是 上網,必須完成兩點,1.你的請求...
移動端的那些坑
首先我們來看乙個結構 div class header div div class main div div class footer textarea textarea div 其實就是最基本的上中下布局而已,問題是header和footer需要分別fixed到頭部和底部。遇到的都知道在ios的s...