GPU加速

瀏覽器器內(nèi)核拿到內(nèi)容(渲染線程接收請求物臂,加載網(wǎng)頁并渲染網(wǎng)頁),渲染大概可以劃分成以下幾個步驟:

  • 解析HTML(HTML Parser)
  • 構(gòu)建DOM樹(DOM Tree)
  • 解析css構(gòu)建render樹(將CSS代碼解析成樹形的數(shù)據(jù)結(jié)構(gòu)瓤介,然后結(jié)合DOM合并成render樹)
  • 布局render樹(Layout/reflow)么抗,負(fù)責(zé)各元素尺寸、位置的計算
  • 繪制render樹(paint)砸抛,繪制頁面像素信息
  • 瀏覽器會將各層的信息發(fā)送給GPU(GPU進程:最多一個评雌,用于3D繪制等),GPU會將各層合成(composite)直焙,顯示在屏幕上

這里先解釋一下幾個概念:

-DOM Tree:瀏覽器將HTML解析成樹形的數(shù)據(jù)結(jié)構(gòu)景东。
-CSS Rule Tree:瀏覽器將CSS解析成樹形的數(shù)據(jù)結(jié)構(gòu)。
-Render Tree: DOM和CSSOM合并后生成Render Tree奔誓。
-layout: 有了Render Tree斤吐,瀏覽器已經(jīng)能知道網(wǎng)頁中有哪些節(jié)點、各個節(jié)點的CSS定義以及他們的從屬關(guān)系,從而去計算出每個節(jié)點在屏幕中的位置曲初。
-painting: 按照算出來的規(guī)則体谒,通過顯卡,把內(nèi)容畫到屏幕上臼婆。
-reflow(回流):當(dāng)瀏覽器發(fā)現(xiàn)某個部分發(fā)生了點變化影響了布局抒痒,需要倒回去重新渲染,這個回退的過程叫 reflow颁褂。reflow 會從 這個 root frame 開始遞歸往下故响,依次計算所有的結(jié)點幾何尺寸和位置。
-repaint(重繪):改變某個元素的背景色颁独、文字顏色彩届、邊框顏色等等不影響它周圍或內(nèi)部布局的屬性時,屏幕的一部分要重畫誓酒,但是元素的幾何尺寸沒有變樟蠕。

注意:
-display:none 的節(jié)點不會被加入Render Tree,而visibility: hidden
則會靠柑,所以寨辩,如果某個節(jié)點最開始是不顯示的,設(shè)為display:none是更優(yōu)的歼冰。

-display:none 會觸發(fā) reflow靡狞,而 visibility:hidden 只會觸發(fā) repaint,因為沒有發(fā)現(xiàn)位置變化隔嫡。

-有些情況下甸怕,比如修改了元素的樣式,瀏覽器并不會立刻reflow 或 repaint 一次腮恩,而是會把這樣的操作積攢一批梢杭,然后做一次reflow,這又叫異步 reflow 或增量異步 reflow庆揪。但是在有些情況下式曲,比如resize窗口,改變了頁面默認(rèn)的字體等缸榛。對于這些操作吝羞,瀏覽器會馬上進行 reflow。

層(layer)

瀏覽器在渲染一個頁面時内颗,會將頁面分為很多個圖層钧排,圖層有大有小,每個圖層上有一個或多個節(jié)點均澳。在渲染DOM的時候恨溜,瀏覽器所做的工作實際上是:

-獲取DOM后分割為多個圖層
-對每個圖層的節(jié)點計算樣式結(jié)果(Recalculate style–樣式重計算)
-為每個節(jié)點生成圖形和位置(Layout–回流和重布局)
-將每個節(jié)點繪制填充到圖層位圖中(Paint Setup和Paint–重繪)
-圖層作為紋理上傳至GPU
-組合多個圖層到頁面上生成最終屏幕圖像(Composite Layers–圖層重組)

紋理(texture)

這里的紋理指的是 GPU 的一個術(shù)語:可以把它想象成一個從主存儲器(例如 RAM)移動到圖像存儲器(例如 GPU 中的 VRAM)的位圖圖像(bitmap image)符衔。一旦它被移動到 GPU 中,你可以將它匹配成一個網(wǎng)格幾何體(mesh geometry)糟袁,在 Chrome 中使用紋理來從 GPU 上獲得大塊的頁面內(nèi)容判族。通過將紋理應(yīng)用到一個非常簡單的矩形網(wǎng)格就能很容易匹配不同的位置(position)和變形(transformation),這也就是 3D CSS 的工作原理项戴。

加速原理

瀏覽器接收到頁面文檔后形帮,會將文檔中的標(biāo)記語言解析為DOM樹。DOM樹和CSS結(jié)合后形成瀏覽器構(gòu)建頁面的渲染樹周叮。渲染樹中包含了大量的渲染元素辩撑,每一個渲染元素會被分到一個圖層中,每個圖層又會被加載到GPU形成渲染紋理仿耽,而圖層在GPU中 transform 是不會觸發(fā) repaint 的合冀,這一點非常類似3D繪圖功能,最終這些使用 transform 的圖層都會由獨立的合成器進程進行處理项贺。

合成層創(chuàng)建標(biāo)準(zhǔn)

Chrome中滿足以下任意情況就會創(chuàng)建圖層:

-3D或透視變換(perspective transform)CSS屬性
-使用加速視頻解碼的節(jié)點
-擁有3D(WebGL)上下文或加速的2D上下文的節(jié)點
-混合插件(如Flash)
-對自己的opacity做CSS動畫或使用一個動畫webkit變換的元素
-擁有加速CSS過濾器的元素
-元素有一個包含復(fù)合層的后代節(jié)點(一個元素?fù)碛幸粋€子元素君躺,該子元素在自己的層里)
-元素有一個z-index較低且包含一個復(fù)合層的兄弟元素(換句話說就是該元素在復(fù)合層上面渲染)

合成層的優(yōu)點

一個元素開啟硬件加速后會變成合成層,可以獨立于普通文檔流中开缎,改動后可以避免整個頁面重繪晰洒,提升性能。

-合成層的位圖啥箭,會交由 GPU 合成,比 CPU 處理要快
-當(dāng)需要 repaint 時治宣,只需要 repaint 本身急侥,不會影響到其他的層
-對于 transform 和 opacity 效果,不會觸發(fā) layout 和 paint

注意:

-提升到合成層后合成層的位圖會交GPU處理侮邀,但請注意坏怪,僅僅只是合成的處理(把繪圖上下文的位圖輸出進行組合)需要用到GPU,生成合成層的位圖處理(繪圖上下文的工作)是需要CPU绊茧。
-當(dāng)需要repaint的時候可以只repaint本身铝宵,不影響其他層,但是paint之前還有style华畏, layout,那就意味著即使合成層只是repaint了自己鹏秋,但style和layout本身就很占用時間。
-僅僅是transform和opacity不會引發(fā)layout 和paint亡笑,那么其他的屬性不確定侣夷。

性能優(yōu)化

-提升動畫效果的元素 合成層的好處是不會影響到其他元素的繪制,因此仑乌,為了減少動畫元素對其他元素的影響百拓,從而減少paint琴锭,我們需要把動畫效果中的元素提升為合成層。 提升合成層的最好方式是使用 CSS 的 will-change屬性衙传。will-change 設(shè)置為opacity决帖、transform、top蓖捶、left地回、bottom、right 可以將元素提升為合成層腺阳。

-使用 transform 或者 opacity 來實現(xiàn)動畫效果, 這樣只需要做合成層的合并就好了落君。

-減少繪制區(qū)域 對于不需要重新繪制的區(qū)域應(yīng)盡量避免繪制,以減少繪制區(qū)域亭引。對于固定不變的區(qū)域绎速,我們期望其并不會被重繪,因此可以將其提升為獨立的合成層焙蚓,減少繪制區(qū)域纹冤,需要仔細(xì)分析頁面,區(qū)分繪制區(qū)域购公,減少重繪區(qū)域甚至避免重繪萌京。

層的重繪

對于靜態(tài) Web 頁面而言,層在第一次被繪制出來之后將不會被改變宏浩,但對于 Web 動畫知残,頁面的 DOM 元素是在不斷變換的,如果層的內(nèi)容在變換過程中發(fā)生了改變比庄,那么層將會被重繪(repaint)求妹。

需要注意的是,如果圖層中某個元素需要重繪佳窑,那么整個圖層都需要重繪制恍。比如一個圖層包含很多節(jié)點,其中一個節(jié)點發(fā)生變化神凑,都會重繪整個圖層的其他節(jié)點净神,然后生成最終的圖層位圖。所以這需要通過特殊的方式來強制這個節(jié)點擁用一個自己的圖層(translateZ(0)或者translate3d(0,0,0))溉委,CSS3的動畫也是一樣(好在絕大部分情況瀏覽器自己會為CSS3動畫的節(jié)點創(chuàng)建圖層)鹃唯。

層和CSS動畫

簡化一下上述過程,每一幀動畫瀏覽器可能需要做如下工作:

-瀏覽器解析 HTML 獲取 DOM 后分割為多個圖層(GraphicsLayer)
-對每個圖層的節(jié)點計算樣式結(jié)果(Recalculate style–樣式重計算)
-為每個節(jié)點生成圖形和位置(Layout–回流和重布局)
-將每個節(jié)點繪制填充到圖層位圖中(Paint Setup和Paint–重繪)
-圖層作為紋理(texture)上傳至 GPU
-組合多個圖層到頁面上生成最終屏幕圖像(Composite Layers–圖層重組)

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

現(xiàn)代瀏覽器如Chrome絮爷,F(xiàn)irefox,Safari和Opera都對變換和透明度采用硬件加速梨树。

CSS 中的以下幾個屬性能觸發(fā)硬件加速:

-transform
-opacity
-filter
-will-change

3D 和 2D transform 的區(qū)別就在于坑夯,瀏覽器在頁面渲染前為3D動畫創(chuàng)建獨立的復(fù)合圖層,而在運行期間為2D動畫創(chuàng)建抡四。動畫開始時柜蜈,生成新的復(fù)合圖層并加載為GPU的紋理用于初始化 repaint。然后由GPU的復(fù)合器操縱整個動畫的執(zhí)行指巡。最后當(dāng)動畫結(jié)束時淑履,再次執(zhí)行 repaint 操作刪除復(fù)合圖層。

強制使用GPU渲染

為了避免 2D transform 動畫在開始和結(jié)束時發(fā)生的 repaint 操作藻雪,我們可以硬編碼一些樣式來解決這個問題:

.example1 {
  transform: translateZ(0);
}

.example2 {
  transform: rotateZ(360deg);
}

這段代碼的作用就是讓瀏覽器執(zhí)行 3D transform秘噪。瀏覽器通過該樣式創(chuàng)建了一個獨立圖層,圖層中的動畫則有GPU進行預(yù)處理并且觸發(fā)了硬件加速勉耀。

如果某一個元素的背后是一個復(fù)雜元素指煎,那么該元素的 repaint 操作就會耗費大量的資源,此時也可以使用上面的技巧來減少性能開銷便斥。

使用硬件加速的注意事項

-內(nèi)存至壤。如果GPU加載了大量的紋理,那么很容易就會發(fā)生內(nèi)容問題枢纠,這一點在移動端瀏覽器上尤為明顯像街,所以,一定要牢記不要讓頁面的每個元素都使用硬件加速晋渺。

-使用GPU渲染會影響字體的抗鋸齒效果宅广。這是因為GPU和CPU具有不同的渲染機制。即使最終硬件加速停止了些举,文本還是會在動畫期間顯示得很模糊。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末俭厚,一起剝皮案震驚了整個濱河市户魏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挪挤,老刑警劉巖叼丑,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扛门,居然都是意外死亡鸠信,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門论寨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來星立,“玉大人爽茴,你說我怎么就攤上這事〈麓梗” “怎么了室奏?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長劲装。 經(jīng)常有香客問我胧沫,道長,這世上最難降的妖魔是什么占业? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任绒怨,我火速辦了婚禮,結(jié)果婚禮上谦疾,老公的妹妹穿的比我還像新娘南蹂。我一直安慰自己,他們只是感情好餐蔬,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布碎紊。 她就那樣靜靜地躺著,像睡著了一般樊诺。 火紅的嫁衣襯著肌膚如雪仗考。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天词爬,我揣著相機與錄音秃嗜,去河邊找鬼。 笑死顿膨,一個胖子當(dāng)著我的面吹牛锅锨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播恋沃,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼必搞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了囊咏?” 一聲冷哼從身側(cè)響起恕洲,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梅割,沒想到半個月后霜第,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡户辞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年泌类,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片底燎。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡刃榨,死狀恐怖弹砚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情喇澡,我是刑警寧澤迅栅,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站晴玖,受9級特大地震影響读存,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜呕屎,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一让簿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧秀睛,春花似錦尔当、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至田盈,卻和暖如春畜号,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背允瞧。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工简软, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人述暂。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓痹升,卻偏偏與公主長得像,于是被迫代替她去往敵國和親畦韭。 傳聞我的和親對象是個殘疾皇子疼蛾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

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