摘要:前瞻目前正在探究通過的多線程來提供更好的動畫效果,而不會觸發重布局及樣式重計算結論動畫給予了頁面豐富的視覺體驗。最好提前申明動畫,這樣能讓瀏覽器提前對動畫進行優化。
正巧看到在送書,于是乎找了找自己博客上記錄過的一些東西來及其無恥的蹭書了~~~
小廣告:更多內容可以看我的博客
最近拜讀了一下html5rocks上幾位大神寫的一篇關于CSS3動畫性能優化的文章,學到了很多,在這里記錄一下,其中的知識都是來源于這倆篇文章,我只是截取了其中比較關注的內容出來,原文地址High Performance Animations及Accelerated Rendering in Chrome
原理現代瀏覽器在使用CSS3動畫時,以下四種情形繪制的效率較高,分別是:
* 改變位置
* 改變大小
* 旋轉
* 改變透明度
首先要了解CSS的圖層的概念(Chrome瀏覽器)
瀏覽器在渲染一個頁面時,會將頁面分為很多個圖層,圖層有大有小,每個圖層上有一個或多個節點。在渲染DOM的時候,瀏覽器所做的工作實際上是:
1. 獲取DOM后分割為多個圖層
2. 對每個圖層的節點計算樣式結果(Recalculate style--樣式重計算)
3. 為每個節點生成圖形和位置(Layout--回流和重布局)
4. 將每個節點繪制填充到圖層位圖中(Paint Setup和Paint--重繪)
5. 圖層作為紋理上傳至GPU
6. 符合多個圖層到頁面上生成最終屏幕圖像(Composite Layers--圖層重組)
Chrome中滿足以下任意情況就會創建圖層:
* 3D或透視變換(perspective transform)CSS屬性
* 使用加速視頻解碼的節點
* 擁有3D(WebGL)上下文或加速的2D上下文的節點
* 混合插件(如Flash)
* 對自己的opacity做CSS動畫或使用一個動畫webkit變換的元素
* 擁有加速CSS過濾器的元素
* 元素有一個包含復合層的后代節點(一個元素擁有一個子元素,該子元素在自己的層里)
* 元素有一個z-index較低且包含一個復合層的兄弟元素(換句話說就是該元素在復合層上面渲染)
需要注意的是,如果圖層中某個元素需要重繪,那么整個圖層都需要重繪。比如一個圖層包含很多節點,其中有個gif圖,gif圖的每一幀,都會重回整個圖層的其他節點,然后生成最終的圖層位圖。所以這需要通過特殊的方式來強制gif圖屬于自己一個圖層(translateZ(0)或者translate3d(0,0,0)),CSS3的動畫也是一樣(好在絕大部分情況瀏覽器自己會為CSS3動畫的節點創建圖層)
層和CSS動畫簡化一下上述過程,每一幀動畫瀏覽器可能需要做如下工作:
1. 計算需要被加載到節點上的樣式結果(Recalculate style--樣式重計算)
2. 為每個節點生成圖形和位置(Layout--回流和重布局)
3. 將每個節點填充到圖層中(Paint Setup和Paint--重繪)
4. 組合圖層到頁面上(Composite Layers--圖層重組)
如果我們需要使得動畫的性能提高,需要做的就是減少瀏覽器在動畫運行時所需要做的工作。最好的情況是,改變的屬性僅僅印象圖層的組合,變換(transform)和透明度(opacity)就屬于這種情況
現代瀏覽器如Chrome,Firefox,Safari和Opera都對變換和透明度采用硬件加速,但IE10+不是很確定是否硬件加速
觸發重布局的屬性有些節點,當你改變他時,會需要重新布局(這也意味著需要重新計算其他被影響的節點的位置和大小)。這種情況下,被影響的DOM樹越大(可見節點),重繪所需要的時間就會越長,而渲染一幀動畫的時間也相應變長。所以需要盡力避免這些屬性
一些常用的改變時會觸發重布局的屬性:
盒子模型相關屬性會觸發重布局:
* width
* height
* padding
* margin
* display
* border-width
* border
* min-height
定位屬性及浮動也會觸發重布局:
* top
* bottom
* left
* right
* position
* float
* clear
改變節點內部文字結構也會觸發重布局:
* text-align
* overflow-y
* font-weight
* overflow
* font-family
* line-height
* vertival-align
* white-space
* font-size
這么多常用屬性都會觸發重布局,可以看到,他們的特點就是可能修改整個節點的大小或位置,所以會觸發重布局
別使用CSS類名做狀態標記如果在網頁中使用CSS的類來對節點做狀態標記,當這些節點的狀態標記類修改時,將會觸發節點的重繪和重布局。所以在節點上使用CSS類來做狀態比較是代價很昂貴的
觸發重繪的屬性修改時只觸發重繪的屬性有:
* 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
這樣可以看到,這些屬性都不會修改節點的大小和位置,自然不會觸發重布局,但是節點內部的渲染效果進行了改變,所以只需要重繪就可以了
手機就算重繪也很慢在重繪時,這些節點會被加載到GPU中進行重繪,這對移動設備如手機的影響還是很大的。因為CPU不如臺式機或筆記本電腦,所以繪畫巫妖的時間更長。而且CPU與GPU之間的有較大的帶寬限制,所以紋理的上傳需要一定時間
觸發圖層重組的屬性 透明度竟然不會觸發重繪?需要注意的是,上面那些觸發重繪的屬性里面沒有opacity(透明度),很奇怪不是嗎?實際上透明度的改變后,GPU在繪畫時只是簡單的降低之前已經畫好的紋理的alpha值來達到效果,并不需要整體的重繪。不過這個前提是這個被修改opacity本身必須是一個圖層,如果圖層下還有其他節點,GPU也會將他們透明化
強迫瀏覽器創建圖層在Blink和WebKit的瀏覽器中,一當一個節點被設定了透明度的相關過渡效果或動畫時,瀏覽器會將其作為一個多帶帶的圖層,但很多開發者使用translateZ(0)或者translate3d(0,0,0)去使瀏覽器創建圖層。這種方式可以消除在動畫開始之前的圖層創建時間,使得動畫盡快開始(創建圖層和繪制圖層還是比較慢的),而且不會隨著抗鋸齒而導出突變。不過這種方法需要節制,否則會因為創建過多的圖層導致崩潰
Chrome中的抗鋸齒Chrome中,非根圖層以及透明圖層使用grayscale antialiasing而不是subpixel antialiasing,如果抗鋸齒方法變化,這個效果將會非常顯著。如果你打算預處理一個節點而不打算等到動畫開始,可以通過這種強迫瀏覽器創建圖層的方式進行
transform變換是你的選擇我們通過節點的transform可以修改節點的位置、旋轉、大小等。我們平常會使用left和top屬性來修改節點的位置,但正如上面所述,left和top會觸發重布局,修改時的代價相當大。取而代之的更好方法是使用translate,這個不會觸發重布局
JS動畫和CSS3動畫的比較我們經常面臨一個抉擇:是使用JavaScript的動畫還是使用CSS的動畫,下面將對比一下這兩種方式
JS動畫缺點:JavaScript在瀏覽器的主線程中運行,而其中還有很多其他需要運行的JavaScript、樣式計算、布局、繪制等對其干擾。這也就導致了線程可能出現阻塞,從而造成丟幀的情況。
優點:JavaScript的動畫與CSS預先定義好的動畫不同,可以在其動畫過程中對其進行控制:開始、暫停、回放、中止、取消都是可以做到的。而且一些動畫效果,比如視差滾動效果,只有JavaScript能夠完成
CSS動畫缺點:缺乏強大的控制能力。而且很難以有意義的方式結合到一起,使得動畫變得復雜且易于出問題。
優點:瀏覽器可以對動畫進行優化。它必要時可以創建圖層,然后在主線程之外運行。
Google目前正在探究通過JS的多線程(Web Workers)來提供更好的動畫效果,而不會觸發重布局及樣式重計算
結論動畫給予了頁面豐富的視覺體驗。我們應該盡力避免使用會觸發重布局和重繪的屬性,以免失幀。最好提前申明動畫,這樣能讓瀏覽器提前對動畫進行優化。由于GPU的參與,現在用來做動畫的最好屬性是如下幾個:
* opacity
* translate
* rotate
* scale
也許會有一些新的方式使得可以使用JavaScript做出更好的沒有限制的動畫,而且不用擔心主線程的阻塞問題。但在那之前,還是好好考慮下如何做出流暢的動畫吧
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/49493.html
摘要:前瞻目前正在探究通過的多線程來提供更好的動畫效果,而不會觸發重布局及樣式重計算結論動畫給予了頁面豐富的視覺體驗。最好提前申明動畫,這樣能讓瀏覽器提前對動畫進行優化。 正巧看到在送書,于是乎找了找自己博客上記錄過的一些東西來及其無恥的蹭書了~~~ 小廣告:更多內容可以看我的博客 最近拜讀了一下html5rocks上幾位大神寫的一篇關于CSS3動畫性能優化的文章,學到了很多,在這里記錄...
摘要:前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點分為新聞熱點開發教程工程實踐深度閱讀開源項目巔峰人生等欄目。它能夠為我們提供類似于預處理器命名空間等多方面的輔助。 前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點;分為新聞熱點、開發教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡迎關注【前端之巔】微信公眾號(ID:f...
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入匯總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業務工作時也會不定期更...
摘要:前言月份開始出沒社區,現在差不多月了,按照工作的說法,就是差不多過了三個月的試用期,準備轉正了一般來說,差不多到了轉正的時候,會進行總結或者分享會議那么今天我就把看過的一些學習資源主要是博客,博文推薦分享給大家。 1.前言 6月份開始出沒社區,現在差不多9月了,按照工作的說法,就是差不多過了三個月的試用期,準備轉正了!一般來說,差不多到了轉正的時候,會進行總結或者分享會議!那么今天我就...
閱讀 2792·2021-09-01 10:30
閱讀 1686·2019-08-30 15:52
閱讀 973·2019-08-29 18:40
閱讀 1129·2019-08-28 18:30
閱讀 2399·2019-08-23 17:19
閱讀 1330·2019-08-23 16:25
閱讀 2703·2019-08-23 16:18
閱讀 2983·2019-08-23 13:53