您可以在這裡瞭解 RenderingNG 的元件 以及轉譯管道的流程
從最高層級開始,轉譯工作如下:
- 將內容轉譯為螢幕上的像素。
- 為內容加入動畫效果。
- 捲動以回應輸入。
- 有效率地將路徑輸入內容轉送至正確的位置,讓開發人員指令碼和其他子系統能做出回應。
要轉譯的內容是每個瀏覽器分頁的頁框樹狀結構,加上 瀏覽器介面此外,還有來自觸控螢幕的原始輸入事件 滑鼠、鍵盤和其他硬體裝置。
每個畫面都包含:
- DOM 狀態
- CSS
- 面板
- 外部資源,例如圖片、影片、字型和 SVG
頁框是指 HTML 文件及其網址。 瀏覽器分頁中載入的網頁具有頂層頁框 每個 iframe 的子頁框 以及相應的遞迴 iframe 子系
視覺效果是指套用至點陣圖的圖形運算、 例如捲動、轉換、裁剪、濾鏡、不透明度或混合
架構元件
在 RenderingNG 中,這些工作會按照邏輯分割至多個階段和程式碼 元件。元件可能會以各種 CPU 程序、執行緒 這些執行緒中的子元件每種類型都扮演著重要角色 穩定性, 可擴充的效能 和擴充性。
轉譯管道結構
![轉譯管道圖表。](https://developer.chrome.com/static/docs/chromium/renderingng-architecture/image/diagram-the-rendering-pi-093c8ed755a54.jpeg?authuser=19&hl=zh-tw)
轉譯作業會在管道中繼續進行,並且已建立多個階段和構件 在整個過程中每個階段都代表程式碼,負責在 算繪。構件是「資料結構」 也就是階段的輸入或輸出內容
階段如下:
- Animate:根據宣告式時間軸變更計算樣式,並隨著時間修改屬性樹狀結構。
- 樣式:將 CSS 套用至 DOM,並建立運算樣式。
- 版面配置:決定 DOM 元素在畫面上的大小和位置。 並建立不可變動的片段樹狀結構。
- 預先繪製:運算屬性樹狀結構和 撤銷 視情況使用任何現有的顯示清單和 GPU 紋理圖塊。
- 捲動:變更屬性樹狀結構,藉此更新文件和可捲動 DOM 元素的捲動偏移。
- 繪製:計算顯示清單,說明如何從 DOM 光柵 GPU 紋理圖塊。
- 「Commit」:將屬性樹狀結構和顯示清單複製到合成器執行緒。
- 「Layerize」:將顯示清單拆分為複合圖層清單,以便執行獨立的光柵化和動畫。
- 光柵、解碼和油漆工作機會:將顯示清單、編碼圖片和油漆工人程式碼分別轉換成 GPU 紋理圖塊。
- 「Activate」(啟動):建立合成器框架,代表如何在畫面上繪製 GPU 圖塊並加上任何視覺效果。
- 「Aggregate」(匯總):將所有可見的合成器影格中的合成器影格合併,成為單一全域合成器框架。
- 繪製:在 GPU 上執行匯總合成器影格,在畫面上建立像素。
您可以略過不需要的算繪管道階段。 舉例來說,視覺效果和捲動的動畫可以略過版面配置、預先繪製和繪製動作。 因此動畫和捲動在圖表中以黃色和綠色圓點標示。 如為版面配置、預先繪製和繪製效果,則可以略過視覺效果 這些執行緒可以完全在合成器執行緒上執行,並略過主執行緒。
這裡未直接描述瀏覽器 UI 轉譯內容 但可以視為同一個 管線的精簡版本 (事實上,實作會共用大部分的程式碼)。 影片 (也未直接呈現) 通常會使用獨立的程式碼進行算繪,進而將影格解碼為 GPU 紋理圖塊 然後將其插入合成器影格和繪製步驟
程序和執行緒結構
CPU 程序
使用多個 CPU 程序可以隔離效能和安全性 切換網站和瀏覽器狀態 以及來自 GPU 硬體的穩定性和安全性區隔
- 轉譯程序會轉譯、動畫、捲動及路徑輸入的 單一網站和分頁組合共有幾種轉譯程序,
- 瀏覽器程序會轉譯、動畫及路徑瀏覽器使用者介面的輸入內容 (包括網址列、分頁標題與圖示),以及所有其他路線 輸入到適當的轉譯程序只有一個瀏覽器程序。
- 「Viz 程序」會匯總多個轉譯程序的合成資料 加上瀏覽器處理程序使用 GPU 光柵和繪圖。另有 一個 Viz 程序。
不同的網站最終會 不同轉譯程序的差異
同一個網站的多個瀏覽器分頁或視窗通常會在不同頁面轉譯 除非分頁具有關聯性 (例如 開啟另一個檔案。 如果使用電腦版 Chromium 的記憶體壓力過大,可能會有多個分頁 即使不相關也是如此
在單一瀏覽器分頁中 不同網站的頁框一律會有不同的轉譯程序 但來自相同網站的影格一律屬於同一個轉譯程序。 從算繪的角度來看 採用多種轉譯程序的重要優勢,在於跨網站 iframe 可以區隔效能 應用程式 此外,來源可以啟用進一步隔離措施。
所有 Chromium 都有一種 Viz 處理程序,因為通常只有 要繪製哪個 GPU 和螢幕
將 Viz 做為專屬流程進行區隔,可讓遊戲過程中發生錯誤, 例如 GPU 驅動程式或硬體此外,它也適合安全隔離 這對 GPU API 而言很重要 Vulkan 和 一般的安全性
由於瀏覽器可以有許多分頁和視窗 而且所有容器都有瀏覽器 UI 像素可以繪製 您可能會好奇,為何究竟是什麼瀏覽器程序呢? 原因在於您一次只有一個網站會聚焦; 實際上,未顯示的瀏覽器分頁大多停用並捨棄所有 GPU 記憶體。 不過,越來越多人導入複雜的瀏覽器 UI 顯示功能 以及轉譯程序中的 WebUI)。 這並非因為效能隔離的原因 但又要善用 Chromium 的網頁轉譯引擎
在舊版 Android 裝置上, 在使用 WebView 時共用轉譯和瀏覽器程序 (不適用於 Android 裝置上的 Chromium,僅適用於 WebView)。 在 WebView 中,瀏覽器程序也會與嵌入應用程式共用 而 WebView 只有一個轉譯程序
有時也有公用程式程序可以解碼受保護的影片內容。 上述圖表並未說明這項程序。
執行緒
執行緒有助於在執行緩慢的工作時隔離效能和回應速度, 管道平行處理和多個緩衝功能
- 主執行緒會執行指令碼、轉譯事件迴圈、文件生命週期。
點擊測試、指令碼事件分派,以及剖析 HTML、CSS 和其他資料格式。
- 主執行緒輔助程式會執行多項工作,例如建立需要編碼或解碼的圖片點陣圖和 blob。
- 網路工作人員 執行指令碼以及 OffscreenCanvas 的轉譯事件迴圈
- 合成器執行緒會處理輸入事件,
會執行網頁內容的捲動和動畫
會計算網路內容的最佳層次
並協調圖片解碼、繪製作業和光柵工作
- 合成器執行緒輔助程式會協調 Viz 光柵工作, 以及執行圖片解碼工作、繪製工作程式和備用光柵
- 媒體、demuxer 或音訊輸出執行緒解碼器, 資料流,並同步處理影片和音訊串流。 (請記住,影片會與主要轉譯管道平行執行)。
區隔主要和合成器執行緒十分重要 效能隔離 以及從主執行緒作業捲動的內容
每個轉譯程序只有一個主要執行緒。 就算同一個網站的多個分頁或頁框也是同一個程序, 不過,也會隔離不同瀏覽器 API 的效能。 舉例來說,在 Canvas API 中產生圖片點陣圖和 blob 時,會在主執行緒輔助執行緒中執行。
同樣地,每個轉譯程序只會有一個合成器執行緒。 這通常不是只有一個問題 因為合成器執行緒上的所有作業都相當昂貴 委派給合成器工作站執行緒或 Viz 程序, 這項工作可透過輸入路徑、捲動或動畫同時完成 合成器工作站執行緒會協調在 Viz 程序中執行的工作。 但所有位置的 GPU 加速功能 測試失敗的原因 例如駕駛錯誤 在這種情況下,背景工作執行緒會在 CPU 上以備用模式執行工作。
合成器工作站執行緒數量取決於裝置功能。 舉例來說,電腦通常會使用較多執行緒, 原因是這類核心的 CPU 核心數更多,且電池有限。 這是 向上擴充與縮減。
轉譯程序執行緒架構是一種三種 最佳化模式:
- 輔助執行緒:將長時間執行的子工作傳送到其他執行緒,以便保持 父項執行緒回應其他同時要求的回應。主執行緒 輔助程式和合成器輔助執行緒是這項技巧的絕佳範例。
- 多重緩衝處理: 顯示先前顯示的內容,以隱藏 延遲時間計算的是轉譯延遲時間合成器執行緒會使用這項技巧。
- 管道平行處理:在多個位置執行轉譯管道 。這就是捲動和動畫的速度。即使 當主執行緒轉譯更新時,捲動和動畫 平行執行
瀏覽器處理程序
- 算繪和合成執行緒會在瀏覽器 UI 中回應輸入內容。 將其他輸入內容轉送至正確的轉譯程序呈現及繪製瀏覽器使用者介面
- 轉譯和組合執行緒輔助程式 執行圖片解碼工作,以及備用光柵或解碼。
瀏覽器程序的轉譯和合成執行緒十分類似 轉譯程序的程式碼和功能 但主執行緒和合成器執行緒會合併為單一執行緒。 就此例而言,您只需要一個執行緒,因為不需要 長時間主要執行緒的工作中,除了效能區隔之外 因為這並非 Android 採用的架構
Viz 程序
- 「GPU 主執行緒」光柵會將清單和影片影格顯示在 GPU 紋理圖塊中。 並在螢幕上繪製合成器框架。
- 顯示合成器執行緒會匯總及最佳化每個轉譯程序的合成作業。 加上瀏覽器程序,形成單一合成器頁框,以便在螢幕上呈現內容。
光柵與繪圖通常在同一個執行緒上進行 兩者都依賴 GPU 資源 以多執行緒方式穩定使用 GPU (開發新的 Vulkan 標準)。 在 Android WebView 中,系統會使用獨立的 OS 層級算繪執行緒 這都要歸功於 WebView 嵌入原生應用程式的方式 其他平台日後可能會有這類訊息討論串。
顯示合成器必須即時回應,因此位於其他執行緒。 且不會阻止 GPU 主執行緒發生速度變慢的原因。 GPU 主執行緒發生速度緩慢的原因之一,就是呼叫非 Chromium 程式碼。 例如廠商專用的 GPU 驅動程式 這些處理速度可能難以預測
元件結構
在每個轉譯程序的主執行緒或合成器執行緒中, 邏輯軟體元件會以結構化方式相互互動,
轉譯程序主執行緒元件
在 Blink Renderer 中:
- 「本機影格樹狀結構」代表本機影格的樹狀結構,以及影格中的 DOM。
- 「DOM 和 Canvas API」元件包含所有這些 API 的實作。
- 文件生命週期執行器會執行轉譯管道步驟,直到執行修訂版本步驟為止。
- 「輸入事件命中測試與分派」元件會執行命中測試, 找出事件指定的 DOM 元素,然後執行輸入事件 分派演算法和預設行為
「算繪事件迴圈排程器和執行器」會決定要在事件上執行哪些內容 以及何時循環播放而是安排在與裝置相配的頻率執行轉譯作業 螢幕。
本機頁框樹狀結構片段有點複雜, 提醒您,頁框樹狀結構是主頁面及其子 iframe,並以遞迴方式進行。 如果影格是透過該程序轉譯,就是轉譯程序的「本機」影格; 或是遠端設定
您可以根據轉譯程序設計為影格著色。 在上圖中,綠色圓圈代表一個轉譯程序中的所有影格; 橘色代表數秒,藍色是第三,
本機頁框樹狀結構片段是影格樹狀結構中相同顏色的連接元件。 圖片中有四個本機頁框樹狀結構:一個用於網站 A、一個用於網站 B,另一個用於網站 C。 每個本機頁框樹狀結構都有自己的 Blink 轉譯器元件。 本機影格樹狀結構的 Blink 轉譯器不一定會處於相同轉譯程序 就如同其他本機框架樹狀結構其取決於選取轉譯程序的方式。
轉譯程序合成器執行緒結構
轉譯程序合成器元件包括:
- 資料處理常式,負責維護複合式圖層清單、顯示清單及屬性樹狀結構。
- 執行動畫、捲動、複合、光柵、執行動畫的生命週期執行器 將轉譯管道的步驟解碼及啟用 (請注意,動畫和捲動都可能發生在主要執行緒和合成器中)。
- 輸入和命中測試處理常式會以複合層的解析度執行輸入處理和命中測試。 判斷捲動手勢是否可以在合成器執行緒上執行, 以及應指定哪些轉譯程序命中測試
架構範例
這個範例中有三個分頁:
分頁 1:foo.com
<html>
<iframe id=one src="foo.com/other-url"></iframe>
<iframe id=two src="bar.com"></iframe>
</html>
分頁 2:bar.com
<html>
…
</html>
分頁 3:baz.com
html
<html>
…
</html>
這些分頁的處理程序、執行緒和元件結構如下:
現在我們來逐一說明算繪這四個主要工作的範例。 提醒事項:
- 將內容算繪為螢幕上的像素。
- 針對內容在不同狀態間的內容動畫效果。
- 捲動以回應輸入。
- 有效率地將輸入內容轉送至正確位置,以便開發人員指令碼和其他子系統做出回應。
如要轉譯分頁 1 中已變更的 DOM:
- 開發人員指令碼會變更 foo.com 的轉譯程序中的 DOM。
- 閃爍轉譯器會通知合成器需要轉譯。
- 合成器會指示 Viz 需要轉譯。
- Viz 會將轉譯的開始傳回給合成器。
- 合成器會將起始訊號轉送至 Blink 轉譯器。
- 主執行緒事件迴圈執行器會執行文件生命週期。
- 主執行緒將結果傳送至合成器執行緒。
- 合成器事件迴圈執行器會執行合成生命週期。
- 任何光柵工作都會傳送至光柵工作 (通常會有多個任務)。
- GPU 上的 Viz 光柵內容。
- Viz 確認完成光柵工作。 注意:Chromium 通常不會等待光柵完成。 而是使用稱為 同步處理權杖 必須先解決的問題 將工作分派至步驟 15 執行前的工作量
- 合成器框架會傳送至 Viz。
- Viz 會匯總 foo.com 轉譯程序的合成器框架, bar.com iframe 轉譯程序,以及瀏覽器 UI
- 維茲排定抽獎時間。
- Viz 會在螢幕上繪製匯總的合成器框架。
如何在第 2 分頁為 CSS 轉換轉換加上動畫效果:
- bar.com 轉譯程序的合成器執行緒會固定顯示動畫 變更現有的屬性樹狀結構,藉此在合成器事件迴圈中使用。 接著,系統會重新執行合成器生命週期。(光柵和解碼工作可能會發生,但此處並未說明此情況)。
- 合成器框架會傳送至 Viz。
- Viz 會匯總 foo.com 轉譯程序、 bar.com 轉譯程序,以及瀏覽器 UI 的合成器框架。
- 維茲排定抽獎時間。
- Viz 會在螢幕上繪製匯總的合成器框架。
如何捲動分頁三上的網頁:
- 一系列
input
事件 (滑鼠、觸控或鍵盤) 皆屬於瀏覽器程序。 - 每個事件都會轉送至 baz.com 的轉譯程序合成器執行緒。
- 合成器會決定主執行緒是否需要瞭解事件。
- 如有需要,系統會將事件傳送至主執行緒。
- 主執行緒會觸發
input
事件監聽器 (pointerdown
、touchstar
、pointermove
、touchmove
或wheel
) 查看事件監聽器是否會在事件上呼叫preventDefault
。 - 主執行緒會傳回是否已向合成器呼叫
preventDefault
。 - 否則系統會將輸入事件傳回瀏覽器程序。
- 瀏覽器程序結合其他近期事件,將轉換轉換為捲動手勢。
- 捲動手勢會再次傳送至 baz.com 的轉譯程序合成器執行緒。
- 在這裡套用捲動,並將 bar.com 的合成器執行緒
轉譯程序會在合成器事件迴圈中放置動畫。
然後,系統會變更屬性樹狀結構中的捲動位移,並重新執行合成器生命週期。
也會指示主執行緒觸發
scroll
事件 (此處未描述)。 - 合成器框架會傳送至 Viz。
- Viz 會匯總 foo.com 轉譯程序的合成器框架, bar.com 轉譯程序,以及瀏覽器 UI
- 維茲排定抽獎時間。
- Viz 會在螢幕上繪製匯總的合成器框架。
如何路徑分頁 1 上 iframe #two 超連結上的 click
事件:
input
事件 (滑鼠、觸控或鍵盤) 用於瀏覽器程序。 可進行近似命中測試 決定 bar.com iframe 轉譯程序收到點擊,並傳送到該處。- bar.com 的合成器執行緒會將
click
事件轉送至主執行緒 並排定處理事件迴圈工作 - bar.com 主要執行緒命中測試的輸入事件處理器,可判斷
有人點擊 iframe 中的 DOM 元素,並觸發
click
事件讓指令碼觀察。 聽不到「preventDefault
」,系統將導向超連結。 - 載入超連結的到達網頁後,就會呈現新狀態。 執行步驟類似於「算繪已變更 DOM」先前的例子 (本文未說明後續變更)。
重點摘要
思考並內部處理轉譯作業可能需要花費大量時間。
最重要的是,您必須謹慎使用轉譯管道 模組化和細節注意力已分割成 獨立元件隨後這些元件 和執行緒 可彈性擴充的效能 和擴充性的機會
每個元件都能發揮關鍵作用 和新型網頁應用程式
請繼續閱讀「主要資料結構」一文。 就和 RenderingNG 一樣重要
插圖:Una Kravets。