浏览器渲染流水线解析与网页动画性能优化
若干年前,我寫(xiě)過(guò)一篇介紹瀏覽器渲染流水線的文章 - How Rendering Work (in WebKit and Blink),這篇文章,一來(lái)部分內(nèi)容已經(jīng)過(guò)時(shí),二來(lái)缺少一個(gè)全局視角來(lái)對(duì)流水線整體進(jìn)行分析,所以打算重新寫(xiě)一篇新的文章,從一個(gè)更高抽象層次和高度簡(jiǎn)化的方式對(duì)瀏覽器的渲染流水線進(jìn)行解析,能讓大部分頁(yè)端同學(xué)都能夠看的明白,并以此作為指引來(lái)分析和優(yōu)化頁(yè)面的渲染/動(dòng)畫(huà)性能。
有些基本概念如圖層,分塊,光柵化基本沒(méi)有發(fā)生變化,如果讀者不理解的話請(qǐng)參考 How Rendering Work (in WebKit and Blink),本文不再過(guò)多解釋。
寫(xiě)這篇文章是始于年初對(duì)頁(yè)端開(kāi)發(fā)高性能(交互/動(dòng)畫(huà)) Mobile WebApp 的一些思考,實(shí)際開(kāi)始寫(xiě)已經(jīng)是年中… 陸陸續(xù)續(xù)寫(xiě)了幾個(gè)月才終于寫(xiě)完。感覺(jué)最難的還是開(kāi)始的部分,要能夠先把基礎(chǔ)的部分講解清楚,然后再循序漸進(jìn)去講解更復(fù)雜的概念。思考了很久,最終決定從幀的概念入手,然后把動(dòng)畫(huà)定義成一個(gè)連續(xù)的幀序列的組合這種方式來(lái)對(duì)動(dòng)畫(huà)進(jìn)行解析,最終成文的效果還是比較讓自己滿意的。
文章是在作業(yè)部落上寫(xiě)的的,然后再把 Markdown 貼到其它網(wǎng)站,無(wú)法保證每個(gè)網(wǎng)站最終呈現(xiàn)的排版效果,如果讀者覺(jué)得排版欠佳,可以訪問(wèn)在作業(yè)部落上發(fā)布的原網(wǎng)址。
本文基于當(dāng)前版本的 Chrome 瀏覽器寫(xiě)成(60 左右),理論上部分知識(shí)可以應(yīng)用于其它瀏覽器(當(dāng)然術(shù)語(yǔ)會(huì)有一定差別)或者 Chrome 后續(xù)的版本,但是并不完全保證這一點(diǎn)。
1. 渲染流水線
上圖顯示了 Chrome 一個(gè)高度簡(jiǎn)化后的渲染流水線示意圖:
當(dāng)我們說(shuō) Compositor,在沒(méi)有加修飾語(yǔ)的情況下,一般都是指 Layer Compositor。另外術(shù)語(yǔ) Child Compositor(子合成器)也是指 Layer Compositor,相對(duì)于作為 Parent 的 Display Compositor 而言。
1.1 進(jìn)程與線程
一個(gè) Chrome 瀏覽器一般會(huì)有一個(gè) Browser 進(jìn)程,一個(gè) GPU 進(jìn)程,和多個(gè) Renderer 進(jìn)程,通常每個(gè) Renderer 進(jìn)程對(duì)應(yīng)一個(gè)頁(yè)面。在特殊架構(gòu)(Android WebView)或者特定配置下,Browser 進(jìn)程可以兼作 GPU 進(jìn)程或者 Renderer 進(jìn)程(意味著沒(méi)有獨(dú)立的 GPU 或者 Renderer 進(jìn)程),但是 Browser 跟 Renderer,Browser 跟 GPU,Renderer 跟 GPU 之間的系統(tǒng)架構(gòu)和通訊方式基本保持不變,線程架構(gòu)也是同樣。
Display Compositor 后面應(yīng)該會(huì)移到 GPU 進(jìn)程的主 GPU 線程,當(dāng)然對(duì)父子合成器進(jìn)行調(diào)度的部分仍然是在 Browser 進(jìn)程的 UI 線程,不太確定各個(gè)不不同平臺(tái)的狀況,Android WebView 平臺(tái)是已經(jīng)實(shí)現(xiàn)了。
1.2 幀
所有的渲染流水線都會(huì)有幀的概念,幀這個(gè)概念抽象描述了渲染流水線下級(jí)模塊往上級(jí)模塊輸出的繪制內(nèi)容相關(guān)數(shù)據(jù)的封裝。我們可以看到 Blink 輸出 Main Frame 給 Layer Compositor,Layer Compositor 輸出 Compositor Frame 給 Display Compositor,Display Compositor 輸出 GL Frame 給 Window。我們覺(jué)得一個(gè)動(dòng)畫(huà)是否流暢,最終取決于 GL Frame 的幀率(也就是目標(biāo)窗口的繪制更新頻率),而覺(jué)得一個(gè)觸屏操作是否響應(yīng)即時(shí),取決于從 Blink 處理事件到 Window 更新的整個(gè)過(guò)程的耗時(shí)(理論上應(yīng)該還要加上事件從 Browser 發(fā)送給 Compositor,再發(fā)送給 Blink 的這個(gè)過(guò)程的耗時(shí))。
1.1.1 Main Frame
Main Frame 包含了對(duì)網(wǎng)頁(yè)內(nèi)容的描述,主要以繪圖指令的形式,或者可以簡(jiǎn)單理解為某個(gè)時(shí)間點(diǎn)對(duì)整個(gè)網(wǎng)頁(yè)的一個(gè)矢量圖快照(可以局部更新)。當(dāng)前版本的 Chrome,圖層化的決策仍然由 Blink 來(lái)負(fù)責(zé),Blink 需要決定如何根據(jù)網(wǎng)頁(yè)的 DOM 樹(shù)來(lái)生成一顆圖層樹(shù),并以 DisplayList 的形式記錄每個(gè)圖層的內(nèi)容(未來(lái)圖層化決策應(yīng)該會(huì)轉(zhuǎn)移到 Layer Compositor,Blink 只輸出 DisplayList 樹(shù)和 DisplayList 節(jié)點(diǎn)的關(guān)鍵屬性,同時(shí) DisplayList 不再以圖層作為單位,而是以每個(gè)排版對(duì)象作為單位)。
圖層化決策一般由以下幾個(gè)因素決定:
第三點(diǎn)是可以被頁(yè)端所直接控制來(lái)優(yōu)化圖層結(jié)構(gòu)及 Main Frame 性能,像傳統(tǒng)的 translate3d hack 和新的 CSS 屬性 will-change。
1.2.2 Compositor Frame
Layer Compositor 接收 Blink 生成的 Main Frame,并轉(zhuǎn)換成合成器內(nèi)部的圖層樹(shù)結(jié)構(gòu)(因?yàn)閳D層化決策仍然由 Blink 負(fù)責(zé),所以這里的轉(zhuǎn)換基本上可以認(rèn)為是生成一棵同樣的樹(shù),再逐個(gè)對(duì)圖層進(jìn)行拷貝)。
Layer Compositor 需要為每個(gè)圖層進(jìn)行分塊,為每個(gè)分塊分配 Resource(Texture 的封裝),然后安排光柵化任務(wù)。
當(dāng) Layer Compositor 接收到來(lái)自 Browser 的繪制請(qǐng)求時(shí),它會(huì)為當(dāng)前可見(jiàn)區(qū)域的每個(gè)圖層的每個(gè)分塊生成一個(gè) Draw Quad 的繪制指令(矩形繪制,指令實(shí)際上指定了坐標(biāo),大小,變換矩陣等屬性),所有的 Draw Quad 指令和對(duì)應(yīng)的 Resource 的集合就構(gòu)成了 Compositor Frame。Compositor Frame 被發(fā)送往 Browser,并最終到達(dá) Display Compositor(未來(lái)也可以直接發(fā)給 Display Compositor)。
1.2.3 GL Frame
Display Compositor 將 Compositor Frame 的每個(gè) Draw Quad 繪制指令轉(zhuǎn)換一個(gè) GL 多邊形繪圖指令,使用對(duì)應(yīng) Resource 封裝的 Texture 對(duì)目標(biāo)窗口進(jìn)行貼圖,這些 GL 繪圖指令的集合就構(gòu)成了一個(gè) GL Frame,最終由 GPU 執(zhí)行這些 GL 指令完成網(wǎng)頁(yè)在窗口上占據(jù)的可見(jiàn)區(qū)域的繪制。
1.3 調(diào)度
Chrome 渲染流水線的調(diào)度是基于請(qǐng)求和狀態(tài)機(jī)響應(yīng),調(diào)度的最上級(jí)中樞運(yùn)行在 Browser UI 線程,它按顯示器的 VSync(垂直同步)周期向 Layer Compositor 發(fā)出輸出下一幀的請(qǐng)求,而 Layer Compositor 根據(jù)自身狀態(tài)機(jī)的狀態(tài)決定是否需要 Blink 輸出下一幀。
Display Compositor 則比較簡(jiǎn)單,它持有一個(gè) Compositor Frame 的隊(duì)列不斷的進(jìn)行取出和繪制,輸出的頻率唯二地取決于 Compositor Frame 的輸入頻率和自身繪制 GL Frame 的耗時(shí)。基本上可以認(rèn)為 Layer Compositor 和 Display Compositor 是生產(chǎn)者和消費(fèi)者的關(guān)系。
2. 網(wǎng)頁(yè)動(dòng)畫(huà)
動(dòng)畫(huà)可以看做是一個(gè)連續(xù)的幀序列的組合。我們把網(wǎng)頁(yè)的動(dòng)畫(huà)分成兩大類(lèi) —— 一類(lèi)是合成器動(dòng)畫(huà),一類(lèi)是非合成器動(dòng)畫(huà)(UC 內(nèi)部也將其稱(chēng)為內(nèi)核動(dòng)畫(huà)或者 Blink Animation,雖然這不是 Chrome 官方的術(shù)語(yǔ))。
2.1 合成器動(dòng)畫(huà)
合成器動(dòng)畫(huà)又可以分為兩類(lèi):
Blink 觸發(fā)的動(dòng)畫(huà),如果是 Transform 和 Opacity 屬性的動(dòng)畫(huà)基本上都可以由合成器運(yùn)行,因?yàn)樗鼈儧](méi)有改變圖層的內(nèi)容。不過(guò)即使可以交由合成器運(yùn)行,它們也需要產(chǎn)生一個(gè)新的 Main Frame 提交給合成器來(lái)觸發(fā)這個(gè)動(dòng)畫(huà),如果這個(gè) Main Frame 包含了大量的圖層變更,也會(huì)導(dǎo)致觸發(fā)的瞬間卡頓,頁(yè)端事先對(duì)圖層結(jié)構(gòu)進(jìn)行優(yōu)化可以避免這個(gè)問(wèn)題。
2.2 非合成器動(dòng)畫(huà)
非合成器動(dòng)畫(huà)也可以分為兩類(lèi):
合成器動(dòng)畫(huà)和非合成器動(dòng)畫(huà)在渲染流水線上有較大的差異,后者更復(fù)雜,流水線更長(zhǎng)。上面四種動(dòng)畫(huà)的分類(lèi),按渲染流水線的復(fù)雜程度和理論性能排列(復(fù)雜程度由低到高,理論性能由高到低):
長(zhǎng)久以來(lái),瀏覽器渲染流水線的設(shè)計(jì)都主要是為了合成器動(dòng)畫(huà)的性能而優(yōu)化,甚至在某種程度上導(dǎo)致非合成器動(dòng)畫(huà)性能的下降,比如說(shuō)合成器的異步光柵化機(jī)制。不過(guò)這兩年,隨著對(duì) WebApp 渲染性能包括 WebGL 性能的重視,并且隨著主流移動(dòng)設(shè)備的硬件性能持續(xù)提升,合成器動(dòng)畫(huà)的性能也已經(jīng)基本不成問(wèn)題,Chrome 的渲染流水線已經(jīng)更多地針對(duì)非合成器動(dòng)畫(huà)的性能進(jìn)行優(yōu)化,甚至?xí)?dǎo)致在某些特定狀況下合成器動(dòng)畫(huà)性能的下降,比方說(shuō)傾向于為了維持圖層樹(shù)的穩(wěn)定性,減少變更,而生成更多的圖層。不過(guò)總的說(shuō)來(lái),目前 Chrome 的渲染流水線,在主流的移動(dòng)設(shè)備上,大部分場(chǎng)景下,兩者性能都能獲得一個(gè)較好的平衡。
3. 動(dòng)畫(huà)性能分析基礎(chǔ)
這里的性能分析主要是針對(duì)移動(dòng)設(shè)備,以桌面處理器的性能,大部分場(chǎng)景下都不存在性能問(wèn)題。目前移動(dòng)設(shè)備的屏幕刷新率基本上都是 60hz,而瀏覽器跟其它應(yīng)用一樣,需要跟屏幕刷新保持垂直同步,也就是動(dòng)畫(huà)幀率的上限是 60 幀,這也是我們能夠達(dá)到的最理想的結(jié)果。不過(guò)考慮瀏覽器本身的復(fù)雜程度,可能有很多后臺(tái)任務(wù)在運(yùn)行,而且操作系統(tǒng)本身也可能同時(shí)運(yùn)行其它后臺(tái)任務(wù),并且移動(dòng)平臺(tái)要考慮能耗和散熱,CPU/GPU 的調(diào)度策略會(huì)頻繁地發(fā)生變化,要完全鎖定 60 幀是非常困難的。
如果上限超過(guò) 60 幀,實(shí)際平均幀率超過(guò) 60 反而不難,但是如果上限是 60 幀,垂直同步下要鎖定 60 幀是非常困難的,要求每一幀的各個(gè)環(huán)節(jié)耗時(shí)都要保持非常穩(wěn)定。
一般而言:
要達(dá)到 50 幀以上的水平,我們就需要對(duì)動(dòng)畫(huà)在渲染流水線的每個(gè)重要環(huán)節(jié)進(jìn)行性能計(jì)算,需要知道這些環(huán)節(jié)最長(zhǎng)允許的耗時(shí)上限和網(wǎng)頁(yè)影響這些環(huán)節(jié)耗時(shí)的主要原因,雖然實(shí)際上很難完全鎖定 60 幀,但是一般來(lái)說(shuō)性能分析/優(yōu)化還是會(huì)以 60 幀為目標(biāo)來(lái)倒推各個(gè)環(huán)節(jié)的最大耗時(shí)。
如果是場(chǎng)景比較復(fù)雜的 Canvas/WebGL 游戲,以 30 幀為目標(biāo)幀率是一個(gè)合理的訴求。
3.1 光柵化機(jī)制
在對(duì)動(dòng)畫(huà)性能進(jìn)行分析之前,需要先說(shuō)明一下目前的 Chrome 的光柵化機(jī)制。合成器會(huì)監(jiān)控是否需要安排新的光柵化任務(wù),當(dāng)需要光柵化調(diào)度時(shí):
實(shí)際的光柵化區(qū)域會(huì)比當(dāng)前可見(jiàn)區(qū)域要更大一些,一般是增加一個(gè)分塊大小單位,對(duì)不可見(jiàn)區(qū)域的預(yù)光柵化有助于提升合成器動(dòng)畫(huà)的性能和減少出現(xiàn)空白的幾率。
從上可知,合成器的光柵化調(diào)度完全是異步的,合成器在 Compositor 線程需要執(zhí)行的就是安排光柵化任務(wù)和檢查哪些任務(wù)已經(jīng)完成,Compositor 線程本身不會(huì)被真正運(yùn)行光柵化任務(wù)的 Worker 線程所阻塞。
4 合成器動(dòng)畫(huà)性能分析和優(yōu)化指南
4.1 動(dòng)畫(huà)流水線
上圖顯示了合成器動(dòng)畫(huà)的渲染流水線示意圖,根據(jù) Android WebView 平臺(tái)的實(shí)現(xiàn)進(jìn)行繪制,其它平臺(tái)可能略微不同,但對(duì)后面的性能分析,在大部分情況下影響不大
整個(gè)流水線的大概過(guò)程是:
4.1 合成器找出在當(dāng)前可見(jiàn)區(qū)域內(nèi)顯示的圖層;
4.2 合成器找出這些圖層在可見(jiàn)區(qū)域內(nèi)的分塊;
4.3 如果該分塊已經(jīng)有分配 Resource(說(shuō)明此分塊已經(jīng)完成光柵化),則產(chǎn)生一個(gè) Draw Quad 的命令置入 Compositor Frame 中,如果沒(méi)有則跳過(guò);
上述流程的一些關(guān)鍵點(diǎn)是:
4.2 動(dòng)畫(huà)耗時(shí)分析
總的來(lái)說(shuō)影響合成器動(dòng)畫(huà)性能的最關(guān)鍵因素就是過(guò)度繪制系數(shù)(Overdraw,可以理解為繪制的面積和可見(jiàn)區(qū)域面積的比例),如果網(wǎng)頁(yè)本身存在大量圖層堆疊情況,導(dǎo)致過(guò)度繪制系數(shù)過(guò)高,就會(huì)嚴(yán)重影響合成器動(dòng)畫(huà)的性能。經(jīng)驗(yàn)顯示,過(guò)度繪制系數(shù)比較理想的值是在 2 以?xún)?nèi),一般建議不超過(guò) 3,這樣可以保證在中低端的移動(dòng)設(shè)備上也有不錯(cuò)的性能表現(xiàn)。
另外,合成器動(dòng)畫(huà)過(guò)程中,Compositor 和 GPU 線程是前臺(tái)線程,它們雖然理論上不會(huì)被 Worker 和 Renderer 線程阻塞,但是在真實(shí)的運(yùn)行場(chǎng)景中,移動(dòng)設(shè)備的 CPU/GPU 和內(nèi)存帶寬等硬件資源是有限的,如果 Worker 和 Renderer 線程處于高負(fù)荷狀態(tài)下,也會(huì)導(dǎo)致前臺(tái)的 Compositor 和 GPU 線程阻塞,最終導(dǎo)致合成器動(dòng)畫(huà)掉幀。
這種現(xiàn)象常見(jiàn)于:
4.3 動(dòng)畫(huà)性能優(yōu)化 Checklist
根據(jù)上述的耗時(shí)分析,我們可以給出一個(gè)頁(yè)端優(yōu)化合成器動(dòng)畫(huà)性能的簡(jiǎn)單 Checklist:
如何判斷網(wǎng)頁(yè)的圖層結(jié)構(gòu)是否穩(wěn)定,一般而言,如果是位于葉子節(jié)點(diǎn)的圖層增加或者移除,對(duì)整個(gè)圖層結(jié)構(gòu)影響并不大,但是如果是中間節(jié)點(diǎn)的圖層增加或者移除,對(duì)圖層結(jié)構(gòu)的影響就比較大了,并且越是接近根節(jié)點(diǎn),影響就越大。
現(xiàn)在的頁(yè)端都會(huì)大量使用異步加載來(lái)優(yōu)化加載性能和流量,但是容易出現(xiàn)導(dǎo)致動(dòng)畫(huà)掉幀的現(xiàn)象。要平衡好這一點(diǎn)意味著需要實(shí)現(xiàn)一個(gè)加載和關(guān)聯(lián) DOM 操作的調(diào)度器,如果檢查到動(dòng)畫(huà)正在運(yùn)行,則停止加載或者通過(guò)節(jié)流閥機(jī)制降低加載的并發(fā)數(shù)量和頻率,同時(shí)可以通過(guò)事先生成相應(yīng)的 DOM 節(jié)點(diǎn)和圖層作為占位符來(lái)避免加載后的圖層結(jié)構(gòu)發(fā)生劇烈變化。
5 非合成器動(dòng)畫(huà)性能分析和優(yōu)化指南
前面已經(jīng)我們已經(jīng)把非合成器動(dòng)畫(huà)區(qū)分為 Blink 觸發(fā),無(wú)法由合成器運(yùn)行的動(dòng)畫(huà)和由 Timer/RAF 驅(qū)動(dòng)的 JS 動(dòng)畫(huà)兩類(lèi),因?yàn)榍罢呖梢哉J(rèn)為是后者的一個(gè)簡(jiǎn)化版本,所以這一章主要討論 Timer/RAF 驅(qū)動(dòng)的 JS 動(dòng)畫(huà)。
5.1 動(dòng)畫(huà)流水線
從上圖可以看出非合成器動(dòng)畫(huà)的流水線比合成器動(dòng)畫(huà)更長(zhǎng)更復(fù)雜,并且非合成器動(dòng)畫(huà)的后半段跟合成器動(dòng)畫(huà)是一致的。
上述流程的一些關(guān)鍵點(diǎn)是:
5.2 動(dòng)畫(huà)耗時(shí)分析和優(yōu)化指南
總的來(lái)說(shuō)對(duì)非合成器動(dòng)畫(huà)性能影響最大的通常是 JavaScript 和 Rasterize,要實(shí)現(xiàn)高性能的非合成器動(dòng)畫(huà),頁(yè)端需要很小心地控制 JavaScript 部分的耗時(shí),并避免在每一幀中引入大面積的網(wǎng)頁(yè)內(nèi)容變化和大幅度的圖層結(jié)構(gòu)變化。另外非合成器動(dòng)畫(huà)的后半段就是合成器動(dòng)畫(huà),所以對(duì)合成器動(dòng)畫(huà)的性能優(yōu)化要求也同樣適用于非合成器動(dòng)畫(huà)。
另外對(duì)于 WebGL 來(lái)說(shuō),當(dāng)在 JavaScript 里面調(diào)用 WebGL API 時(shí),這些命令只是被 Chrome 緩存起來(lái),并不會(huì)在 Renderer 線程調(diào)用真正的 GL API,所以 WebGL API 在 JavaScript 部分的耗時(shí)只是一個(gè) JS Binding 調(diào)用的 Overhead,最終繪制 WebGL 內(nèi)容的 GPU 耗時(shí)實(shí)際上是被包含在最后的 GPU 的步驟里面。但是在移動(dòng)平臺(tái)上一個(gè) JS Binding 調(diào)用的 Overhead 是相當(dāng)高的,大概在 0.01 毫秒這個(gè)范圍,所以每一幀超過(guò) 1000 個(gè) WebGL API 調(diào)用的 WebGL 游戲,性能阻塞的瓶頸有很大概率會(huì)出現(xiàn)在 JavaScript 也就是 CPU 上,而不是 GPU。
6 瀏覽器渲染流水線未來(lái)的演化
看完非合成器動(dòng)畫(huà)流水線分析的讀者,第一感覺(jué)恐怕是覺(jué)得太過(guò)復(fù)雜了,比起合成器動(dòng)畫(huà),更多的線程,更多的中間環(huán)節(jié),有時(shí)即使每個(gè)環(huán)節(jié)都做到了完美,最終也有可能因?yàn)榫€程之間的通訊和等待而導(dǎo)致掉幀。正如前面所說(shuō)的一樣,長(zhǎng)久以來(lái),瀏覽器的渲染流水線都是為了合成器動(dòng)畫(huà)而優(yōu)化的,它的主要特征是:
這兩點(diǎn)實(shí)際上是有利于合成器動(dòng)畫(huà)而不利于非合成器動(dòng)畫(huà)的,瀏覽器渲染流水線當(dāng)前和未來(lái)的演化理所應(yīng)當(dāng)?shù)匾鉀Q這些問(wèn)題。Firefox 新的渲染引擎 WebRender 比較激進(jìn),看起來(lái)是采用流行的 UI Toolkit 如 Qt,Android 的 DisplayList/Scene Graph + Direct Rasterize 的方式,這樣當(dāng)然是有利于非合成器動(dòng)畫(huà)的,但是否會(huì)造成合成器動(dòng)畫(huà)的性能衰退還很難說(shuō)。
Direct Rasterize 的前提條件是瀏覽器渲染引擎要實(shí)現(xiàn) GPU 光柵化,并且性能和兼容性要足夠好。Chrome 當(dāng)前也是在努力推進(jìn) GPU 光柵化,即使整個(gè)流水線的架構(gòu)沒(méi)有發(fā)生變化,GPU 光柵化也可以大幅度減少光柵化在 Worker 線程部分的 CPU 耗時(shí),將這些耗時(shí)轉(zhuǎn)移到 GPU 線程上去,這樣 Main Frame N Active 這部分的耗時(shí)就可以大大減少了。從目前的統(tǒng)計(jì)數(shù)據(jù)來(lái)看,可以使用 GPU 光柵化的移動(dòng)設(shè)備占比已經(jīng)很高,大概 6 成以上的樣子,隨著老舊設(shè)備的淘汰,這個(gè)比例未來(lái)會(huì)越來(lái)越高,并且隨著 GPU 性能的提升,GPU 光柵化的效果也會(huì)越來(lái)越好。
Chrome 另外一個(gè)重點(diǎn)改進(jìn)渲染性能的項(xiàng)目是 Slim Painting,未來(lái) Blink 跟 Firefox 類(lèi)似只輸出 DisplayList 樹(shù),并且每棵 DisplayList 不再是以圖層為單位而是以排版對(duì)象為單位,這樣合成器可以更自由地選擇 Layerize 和 Rasterize 的策略,Async 或者 On Demand 或者 Direct Rasterize 都可以混用來(lái)最大化動(dòng)畫(huà)的性能,合成器可以變得更 Adaptive 而不像現(xiàn)在光柵化和合成區(qū)隔的那么涇渭分明。
除了瀏覽器持續(xù)改進(jìn)自身渲染流水線外,提供更多 API 供頁(yè)端使用來(lái)最大化 WebApp 的性能也是一個(gè)重要的方向,包括:
但是這些新特性要真正應(yīng)用起來(lái),對(duì)頁(yè)端對(duì)瀏覽器渲染流水線的理解要求就更高了。
總結(jié)
以上是生活随笔為你收集整理的浏览器渲染流水线解析与网页动画性能优化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 高级编程语言的发展
- 下一篇: 找不到系统输入法状态图标,怎么办?