H5頁面中CSS3動畫的性能優(yōu)化

CSS3動畫應用很廣,尤其是在H5項目中妆绞,炫酷的交互效果可以給產(chǎn)品帶來更好的體驗,更能吸引用戶枫攀。然而在應用的時候括饶,很多Web前端童鞋可能忽略了一點,就是其性能来涨;不管你是用純CSS3寫的動畫图焰,還是結(jié)合jQuery,性能很重要蹦掐。




網(wǎng)絡(luò)上有很多關(guān)于“CSS3動畫的性能優(yōu)化”的文章技羔,各抒己見,總而言之卧抗,初衷基本一樣藤滥。今天我主要針對一些比較優(yōu)秀的文章和自己的一些見解,總結(jié)一下H5頁面中CSS3動畫的性能優(yōu)化颗味。

在CSS3動畫制作過程中超陆,提升移動端CSS3動畫體驗的主要方法大概有幾點:

1、盡可能多的利用硬件能力,如使用3D變形來開啟GPU加速:

比如代碼:

-webkit-transform:?translate3d(0,?0,?0);

-moz-transform:?translate3d(0,?0,?0);

-ms-transform:?translate3d(0,?0,?0);

transform:?translate3d(0,?0,?0);

一個元素通過translate3d右移500px的動畫流暢度會明顯優(yōu)于使用left屬性时呀;原因:CSS動畫屬性會觸發(fā)整個頁面的重排relayout张漂、重繪repaint、重組recompositePaint通常是其中最花費性能的谨娜,盡可能避免使用觸發(fā)paint的CSS動畫屬性航攒,這也是為什么我們推薦在CSS動畫中使用webkit-transform: translateX(3em)的方案代替使用left: 3em,因為left會額外觸發(fā)layout與paint趴梢,而webkit-transform只觸發(fā)整個頁面composite(這也是為什么推薦在CSS動畫中使用webkit-transform: translateX(500px)的方案代替使用left: 500px)漠畜;

如動畫過程有閃爍(通常發(fā)生在動畫開始的時候),可以嘗試下面的Hack:

-webkit-backface-visibility:?hidden;

-moz-backface-visibility:?hidden;

-ms-backface-visibility:?hidden;

backface-visibility:?hidden;

-webkit-perspective:?1000;

-moz-perspective:?1000;

-ms-perspective:?1000;

perspective:?1000;

2坞靶、盡可能少的使用box-shadows與gradients

box-shadows與gradients往往都是頁面的性能殺手憔狞,尤其是在一個元素同時都使用了它們.

盡可能的讓動畫元素不在文檔流中,以減少重排

position:?fixed;

position:?absolute;

我們一起來看下CSS3動畫其中一些屬性性能消耗圖




性能消耗圖彰阴,由此可見最受歡飲和性能最好的莫過于transform和opacity了瘾敢。

以上只是總結(jié)了2點關(guān)于性能優(yōu)化,后來參閱了一些其他的文章和自己的研究發(fā)現(xiàn):現(xiàn)代瀏覽器在使用CSS3動畫時尿这,以下四種情形繪制的效率較高(包含了以上2種)簇抵。

*改變位置*改變大小*旋轉(zhuǎn)*改變透明度

我們一起來學習下。

層射众?重繪碟摆?回流和重布局?圖層重組叨橱?

首先要了解CSS的圖層的概念(Chrome瀏覽器)

瀏覽器在渲染一個頁面時典蜕,會將頁面分為很多個圖層,圖層有大有小雏逾,每個圖層上有一個或多個節(jié)點嘉裤。在渲染DOM的時候,瀏覽器所做的工作實際上是:1.獲取DOM后分割為多個圖層2.對每個圖層的節(jié)點計算樣式結(jié)果(Recalculate style--樣式重計算)3.為每個節(jié)點生成圖形和位置(Layout--回流和重布局)4.將每個節(jié)點繪制填充到圖層位圖中(Paint Setup和Paint--重繪)5.圖層作為紋理上傳至GPU6.符合多個圖層到頁面上生成最終屏幕圖像(Composite Layers--圖層重組)

Chrome中滿足以下任意情況就會創(chuàng)建圖層:* 3D或透視變換(perspective transform)CSS屬性*使用加速視頻解碼的節(jié)點*擁有3D(WebGL)上下文或加速的2D上下文的節(jié)點*混合插件(如Flash)*對自己的opacity做CSS動畫或使用一個動畫webkit變換的元素*擁有加速CSS過濾器的元素*元素有一個包含復合層的后代節(jié)點(一個元素擁有一個子元素栖博,該子元素在自己的層里)*元素有一個z-index較低且包含一個復合層的兄弟元素(換句話說就是該元素在復合層上面渲染)

需要注意的是屑宠,如果圖層中某個元素需要重繪,那么整個圖層都需要重繪仇让。比如一個圖層包含很多節(jié)點典奉,其中有個gif圖,gif圖的每一幀丧叽,都會重回整個圖層的其他節(jié)點卫玖,然后生成最終的圖層位圖。所以這需要通過特殊的方式來強制gif圖屬于自己一個圖層(translateZ(0)或者translate3d(0,0,0))踊淳,CSS3的動畫也是一樣(好在絕大部分情況瀏覽器自己會為CSS3動畫的節(jié)點創(chuàng)建圖層)

層和CSS動畫

簡化一下上述過程假瞬,每一幀動畫瀏覽器可能需要做如下工作:1.計算需要被加載到節(jié)點上的樣式結(jié)果(Recalculate style--樣式重計算)2.為每個節(jié)點生成圖形和位置(Layout--回流和重布局)3.將每個節(jié)點填充到圖層中(Paint Setup和Paint--重繪)4.組合圖層到頁面上(Composite Layers--圖層重組)

如果我們需要使得動畫的性能提高陕靠,需要做的就是減少瀏覽器在動畫運行時所需要做的工作。最好的情況是脱茉,改變的屬性僅僅印象圖層的組合剪芥,變換(transform)和透明度(opacity)就屬于這種情況

現(xiàn)代瀏覽器如Chrome,F(xiàn)irefox琴许,Safari和Opera都對變換和透明度采用硬件加速税肪,但IE10+不是很確定是否硬件加速

觸發(fā)重布局的屬性

有些節(jié)點,當你改變他時榜田,會需要重新布局(這也意味著需要重新計算其他被影響的節(jié)點的位置和大幸嫘帧)。這種情況下箭券,被影響的DOM樹越大(可見節(jié)點)净捅,重繪所需要的時間就會越長,而渲染一幀動畫的時間也相應變長辩块。所以需要盡力避免這些屬性

一些常用的改變時會觸發(fā)重布局的屬性:盒子模型相關(guān)屬性會觸發(fā)重布局:* width* height* padding* margin* display* border-width* border* min-height

定位屬性及浮動也會觸發(fā)重布局:* top* bottom* left* right* position* float* clear

改變節(jié)點內(nèi)部文字結(jié)構(gòu)也會觸發(fā)重布局:* text-align* overflow-y* font-weight* overflow* font-family* line-height* vertival-align* white-space* font-size

這么多常用屬性都會觸發(fā)重布局灸叼,可以看到,他們的特點就是可能修改整個節(jié)點的大小或位置庆捺,所以會觸發(fā)重布局

別使用CSS類名做狀態(tài)標記

如果在網(wǎng)頁中使用CSS的類來對節(jié)點做狀態(tài)標記,當這些節(jié)點的狀態(tài)標記類修改時屁魏,將會觸發(fā)節(jié)點的重繪和重布局滔以。所以在節(jié)點上使用CSS類來做狀態(tài)比較是代價很昂貴的

觸發(fā)重繪的屬性

修改時只觸發(fā)重繪的屬性有:* color* border-style* border-radius* visibility* text-decoration* background* background-image* background-position* background-repeat* background-size* outline-color* outline* outline-style* outline-width* box-shadow

這樣可以看到,這些屬性都不會修改節(jié)點的大小和位置氓拼,自然不會觸發(fā)重布局你画,但是節(jié)點內(nèi)部的渲染效果進行了改變,所以只需要重繪就可以了

手機就算重繪也很慢

在重繪時桃漾,這些節(jié)點會被加載到GPU中進行重繪坏匪,這對移動設(shè)備如手機的影響還是很大的。因為CPU不如臺式機或筆記本電腦撬统,所以繪畫巫妖的時間更長适滓。而且CPU與GPU之間的有較大的帶寬限制,所以紋理的上傳需要一定時間

觸發(fā)圖層重組的屬性

透明度竟然不會觸發(fā)重繪恋追?

需要注意的是凭迹,上面那些觸發(fā)重繪的屬性里面沒有opacity(透明度),很奇怪不是嗎苦囱?實際上透明度的改變后嗅绸,GPU在繪畫時只是簡單的降低之前已經(jīng)畫好的紋理的alpha值來達到效果,并不需要整體的重繪撕彤。不過這個前提是這個被修改opacity本身必須是一個圖層鱼鸠,如果圖層下還有其他節(jié)點,GPU也會將他們透明化

強迫瀏覽器創(chuàng)建圖層

在Blink和WebKit的瀏覽器中,一當一個節(jié)點被設(shè)定了透明度的相關(guān)過渡效果或動畫時蚀狰,瀏覽器會將其作為一個單獨的圖層愉昆,但很多開發(fā)者使用translateZ(0)或者translate3d(0,0,0)去使瀏覽器創(chuàng)建圖層。這種方式可以消除在動畫開始之前的圖層創(chuàng)建時間造锅,使得動畫盡快開始(創(chuàng)建圖層和繪制圖層還是比較慢的)撼唾,而且不會隨著抗鋸齒而導出突變。不過這種方法需要節(jié)制哥蔚,否則會因為創(chuàng)建過多的圖層導致崩潰

Chrome中的抗鋸齒

Chrome中倒谷,非根圖層以及透明圖層使用grayscale antialiasing而不是subpixel antialiasing,如果抗鋸齒方法變化糙箍,這個效果將會非常顯著渤愁。如果你打算預處理一個節(jié)點而不打算等到動畫開始,可以通過這種強迫瀏覽器創(chuàng)建圖層的方式進行深夯。

transform變換是你的選擇

我們通過節(jié)點的transform可以修改節(jié)點的位置抖格、旋轉(zhuǎn)、大小等咕晋。我們平常會使用left和top屬性來修改節(jié)點的位置雹拄,但正如上面所述,left和top會觸發(fā)重布局掌呜,修改時的代價相當大滓玖。取而代之的更好方法是使用translate,這個不會觸發(fā)重布局质蕉。

JS動畫和CSS3動畫的比較

我們經(jīng)常面臨一個抉擇:是使用JavaScript的動畫還是使用CSS的動畫势篡,下面將對比一下這兩種方式。

JS動畫

缺點:JavaScript在瀏覽器的主線程中運行模暗,而其中還有很多其他需要運行的JavaScript禁悠、樣式計算、布局兑宇、繪制等對其干擾碍侦。這也就導致了線程可能出現(xiàn)阻塞,從而造成丟幀的情況顾孽。

優(yōu)點:JavaScript的動畫與CSS預先定義好的動畫不同祝钢,可以在其動畫過程中對其進行控制:開始、暫停若厚、回放拦英、中止、取消都是可以做到的测秸。而且一些動畫效果疤估,比如視差滾動效果灾常,只有JavaScript能夠完成。

CSS動畫

缺點:缺乏強大的控制能力铃拇。而且很難以有意義的方式結(jié)合到一起钞瀑,使得動畫變得復雜且易于出問題。優(yōu)點:瀏覽器可以對動畫進行優(yōu)化慷荔。它必要時可以創(chuàng)建圖層雕什,然后在主線程之外運行。

前瞻

Google目前正在探究通過JS的多線程(Web Workers)來提供更好的動畫效果显晶,而不會觸發(fā)重布局及樣式重計算贷岸。

結(jié)論

動畫給予了頁面豐富的視覺體驗。我們應該盡力避免使用會觸發(fā)重布局和重繪的屬性磷雇,以免失幀偿警。最好提前申明動畫,這樣能讓瀏覽器提前對動畫進行優(yōu)化唯笙。由于GPU的參與螟蒸,現(xiàn)在用來做動畫的最好屬性是如下幾個:* opacity* translate* rotate* scale

也許會有一些新的方式使得可以使用JavaScript做出更好的沒有限制的動畫,而且不用擔心主線程的阻塞問題崩掘。但在那之前七嫌,還是好好考慮下如何做出流暢的動畫吧。

OK苞慢,CSS3動畫的性能優(yōu)化抄瑟,大概的內(nèi)容就是這么多,其實這些遠遠不夠枉疼,更多的還得我們自己去研究和學習。

來源:Web前端之家

原文標題:關(guān)于H5頁面中CSS3動畫的性能優(yōu)化

=

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鞋拟,一起剝皮案震驚了整個濱河市骂维,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贺纲,老刑警劉巖航闺,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異猴誊,居然都是意外死亡潦刃,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門懈叹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乖杠,“玉大人,你說我怎么就攤上這事澄成‰嗜鳎” “怎么了畏吓?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長卫漫。 經(jīng)常有香客問我菲饼,道長,這世上最難降的妖魔是什么列赎? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任宏悦,我火速辦了婚禮,結(jié)果婚禮上包吝,老公的妹妹穿的比我還像新娘饼煞。我一直安慰自己,他們只是感情好漏策,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布派哲。 她就那樣靜靜地躺著,像睡著了一般掺喻。 火紅的嫁衣襯著肌膚如雪芭届。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天感耙,我揣著相機與錄音褂乍,去河邊找鬼。 笑死即硼,一個胖子當著我的面吹牛逃片,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播只酥,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼褥实,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了裂允?” 一聲冷哼從身側(cè)響起损离,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绝编,沒想到半個月后僻澎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡十饥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年窟勃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逗堵。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡秉氧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蜒秤,到底是詐尸還是另有隱情谬运,我是刑警寧澤隙赁,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站梆暖,受9級特大地震影響伞访,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜轰驳,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一厚掷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧级解,春花似錦冒黑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至芒划,卻和暖如春冬竟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背民逼。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工泵殴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拼苍。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓笑诅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親疮鲫。 傳聞我的和親對象是個殘疾皇子吆你,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 原理 現(xiàn)代瀏覽器在使用CSS3動畫時,以下四種情形繪制的效率較高俊犯,分別是: 改變位置 改變大小 旋轉(zhuǎn) 改變透明度 ...
    ddai_Q閱讀 3,780評論 0 11
  • 原理 現(xiàn)代瀏覽器在使用CSS3動畫時早处,以下四種情形繪制的效率較高,分別是: 改變位置(translate) 改變大...
    codeice閱讀 668評論 0 0
  • 一瘫析、CSS的圖層的概念 瀏覽器在渲染一個頁面時,會將頁面分為很多個圖層默责,圖層有大有小贬循,每個圖層上有一個或多個節(jié)點。...
    一只dororo閱讀 748評論 0 1
  • 在iOS中隨處都可以看到絢麗的動畫效果桃序,實現(xiàn)這些動畫的過程并不復雜杖虾,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,465評論 6 30
  • 在iOS中隨處都可以看到絢麗的動畫效果媒熊,實現(xiàn)這些動畫的過程并不復雜奇适,今天將帶大家一窺iOS動畫全貌坟比。在這里你可以看...
    F麥子閱讀 5,094評論 5 13