高效能 CSS3 動畫

2022-03-07 08:46:46 字數 4558 閱讀 5076

本帖最後由 quanyaji 於 2013-8-14 16:29 編輯

... e-css3-animation.md

高效能 css3 動畫

關於流暢度,主要體現在前端動畫中,在現有的前端動畫體系中,通常有兩種模式:js動畫與css3動畫。

js動畫是通過js動態改寫樣式實現動畫能力的一種方案,在pc端相容低端瀏覽器中不失為一種推薦方案。

而在移動端,我們選擇效能更優瀏覽器原生實現方案:css3動畫。

然而,css3動畫在移動多終端裝置場景下,相比pc會面對更多的效能問題,主要體現在動畫的卡頓與閃爍。

目前對提公升移動端css3動畫體驗的主要方法有幾點:

盡可能多的利用硬體能力,如使用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);

如動畫過程有閃爍(通常發生在動畫開始的時候),可以嘗試下面的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;

如下面乙個元素通過translate3d右移500px的動畫流暢度會明顯優於使用left屬性:

#ball-1

#ball-1.slidein

#ball-2

#ball-2.slidein

盡可能少的使用box-shadows與gradients

box-shadows與gradients往往都是頁面的效能殺手,尤其是在乙個元素同時都使用了它們,所以擁抱扁平化設計吧。

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

position: fixed;

position: absolute;

優化 dom layout 效能

我們從例項開始描述這個主題:

var newwidth = adiv.offsetwidth + 10;

adiv.style.width = newwidth + 'px';

var newheight = adiv.offsetheight + 10;

adiv.style.height = newheight + 'px';

var newwidth = adiv.offsetwidth + 10;

var newheight = adiv.offsetheight + 10;

adiv.style.width = newwidth + 'px';

adiv.style.height = newheight + 'px';

這是兩段能力上完全等同的**,顯式的差異正如我們所見,只有執行順序的區別。但真是如此嗎?下面是加了說明注釋的**版本,很好的闡述了其中的進一步差異:

// 觸發兩次 layout

var newwidth = adiv.offsetwidth + 10;   // read

adiv.style.width = newwidth + 'px';     // write

var newheight = adiv.offsetheight + 10; // read

adiv.style.height = newheight + 'px';   // write

// 只觸發一次 layout

var newwidth = adiv.offsetwidth + 10;   // read

var newheight = adiv.offsetheight + 10; // read

adiv.style.width = newwidth + 'px';     // write

adiv.style.height = newheight + 'px';   // write

從注釋中可找到規律,連續的讀取offsetwidth/height屬性與連續的設定width/height屬性,相比分別讀取設定單個屬性可少觸發一次layout。

從結論看似乎與執行佇列有關,沒錯,這是瀏覽器的優化策略。所有可觸發layout的操作都會被暫時放入 layout-queue 中,等到必須更新的時候,再計算整個佇列中所有操作影響的結果,如此就可只進行一次的layout,從而提公升效能。

關鍵一,可觸發layout的操作,哪些操作下會layout的更新(也稱為reflow或者relayout)?

我們從瀏覽器的原始碼實現入手,以開源webkit/blink為例, 對layout的更新,webkit 主要通過

document::updatelayout 與 document::updatelayoutignorependingstylesheets

兩個方法:

void document::updatelayout()

if (element* oe = ownerelement())

oe->document()->updatelayout();

updatestyleifneeded();

stackstats::layoutcheckpoint layoutcheckpoint;

if (frameview && renderer() && (frameview->layoutpending() || renderer()->needslayout()))

frameview->layout();

if (m_focusednode && !m_didpostcheckfocusednodetask)

}void document::updatelayoutignorependingstylesheets()

else if (m_hasnodeswithplaceholderstyle)

recalcstyle(force);

}updatelayout();

m_ignorependingstylesheets = oldignore;

}從 updatelayoutignorependingstylesheets 方法的內部實現可知,其也是對

updatelayout 方法的擴充套件,並且在現有的 layout 更新模式中,大部分場景都是呼叫

updatelayoutignorependingstylesheets 來進行layout的更新。

搜尋 webkit 實現中呼叫 updatelayoutignorependingstylesheets 方法的**, 得到以下可導致觸發 layout 的操作:

element: clientheight, clientleft, clienttop, clientwidth,

focus(), getboundingclientrect(), getclientrects(), innertext,

offsetheight, offsetleft, offsetparent, offsettop, offsetwidth,

outertext, scrollbylines(), scrollbypages(), scrollheight,

scrollintoview(), scrollintoviewifneeded(), scrollleft, scrolltop,

scrollwidth

frame, htmlimageelement: height, width

range: getboundingclientrect(), getclientrects()

svglocatable: computectm(), getbbox()

svgtextcontent: getcharnumatposition(),

getcomputedtextlength(), getendpositionofchar(), getextentofchar(),

getnumberofchars(), getrotationofchar(), getstartpositionofchar(),

getsubstringlength(), selectsubstring()

svguse: instanceroot

window: getcomputedstyle(), scrollby(), scrollto(), scrollx,

scrolly, webkitconvertpointfromnodetopage(),

webkitconvertpointfrompagetonode()

進一步深入layout,那上文中必須更新的必要條件是什麼? 在 stoyan stefanov 的 rendering: repaint, reflow/relayout, restyle 一文中已做比較詳細的解答,可移步了解~

複製**

高效能 CSS3 動畫

關於流暢度,主要體現在前端動畫中,在現有的前端動畫體系中,通常有兩種模式 js動畫與css3動畫。js動畫是通過js動態改寫樣式實現動畫能力的一種方案,在pc端相容低端瀏覽器中不失為一種推薦方案。而在移動端,我們選擇效能更優瀏覽器原生實現方案 css3動畫。然而,css3動畫在移動多終端裝置場景下,...

高效能 CSS3 動畫

關於流暢度,主要體現在前端動畫中,在現有的前端動畫體系中,通常有兩種模式 js動畫與css3動畫。js動畫是通過js動態改寫樣式實現動畫能力的一種方案,在pc端相容低端瀏覽器中不失為一種推薦方案。而在移動端,我們選擇效能更優瀏覽器原生實現方案 css3動畫。然而,css3動畫在移動多終端裝置場景下,...

高效能 CSS3 動畫

關於流暢度,主要體現在前端動畫中,在現有的前端動畫體系中,通常有兩種模式 js動畫與css3動畫。js動畫是通過js動態改寫樣式實現動畫能力的一種方案,在pc端相容低端瀏覽器中不失為一種推薦方案。而在移動端,我們選擇效能更優瀏覽器原生實現方案 css3動畫。然而,css3動畫在移動多終端裝置場景下,...