瀏覽器的渲染與頁面優化

Peter Chang
6 min readJun 30, 2018

--

一個高流𣈱度的網頁,就是一件藝術作品。網頁工匞必須具備三元素知識,:HTMLJavascriptCSS。除了寫出高質量的程式碼,也要確保相關的第三方程式碼是高品質的。

這篇文章,是整理2位巨人 Paul LewisIlya Grigorik 的文章,在討論瀏覽器的渲染過程,和 Rendering Tree 對生成頁面組成。當電腦的速度變慢,我們至少知道要加入更強大的 CPU 或 RAM,才能對症下藥。瀏覽器的優化一樣要對症下藥。

1. 記住 60fps

大部份的裝置:手機和電腦,畫面每秒更新60次 (60 frame pre second 又叫60幀)。當網頁要完成一個動畫,或完成滾動動作,瀏覽器需要協調網頁和裝置,每一次更新畫面時,放入對應的新圖片,以完成動畫。

理論上每幀所消耗的成本是 16ms (1 second / 60 = 16.66ms),實際上瀏覽器每秒七手八腳地更新 60張新圖片,時間緊迫,我們必須在 10ms 內完成處理變動的圖片。當無法在 10ms 內完成工作, fps 就會下降,出現畫面遲鈍;當程式的 fps 高於 60fps,就會造成資源浪費(jank),用戶體驗差。所以最優化的狀況是每秒更新 60次 (60fps)

2. 像素化五步曲

像素化過程 The pixel pipeline

關於渲染,瀏覽器可分成5個部份,Pixel Pipeline (像素化過程),也是網頁流𣈱度進行優化的5把鑰匙。

https://developers.google.com/web/fundamentals/performance/rendering/
  • JavaScript. 基本上 Javascript 用作處理網頁畫面的改變,可以是動作,資料的排序或新增 DOM 元素。
  • 樣式運算 Style calculations. 這個過程負責整理出CSS 規則(CSS Rules) 放到符合選擇器 (Selector) 的 DOM 元素。
    例如: .headline or .nav > .nav__item.
  • 佈局 Layout. 瀏覽器精確地計算每個元素(Element)在頁面的位置,大小。而且也會運算元素間的相互效應,和樣式之間的繼承。例如<body>元素的 width 由上至下影響子元素的 width.
  • 畫 Paint. 想像它是拿著筆上色的過程,對螢幕像素填上顏色的步驟。他把文字寫出來,把圖片畫出來,顏色、邊框和陰影呈現在 DOM 元素上。
    畫的過程出現一層疊一層的畫,應為 Layer (圖層)
  • 合成 Compositing. 當畫面上的元素被畫好了,放在不同的圖層。 而且圖層正在等待被放置到網頁的正確位置,準備好被正確地渲染。

五個步驟網頁資源浪費(Jank)的嫌疑犯,就是上面提到的五個步驟。你必須全盤掌握你所寫的程式碼,到底在將像數化過程(Pixel Pipeline)中產生什麼化學反應。

實際情況下, 不必無時無刻觀察着將像化過程的每個細節,一般修改網頁內容,可以收窄為3種渲染方式。

2.1. JS / CSS > Style > Layout > Paint > Composite

影響佈局(Layout),是徹底上的把頁面重畫一次

當網頁上的元素, 被修改到 Layout Property,例如 width, height, 或 left top,瀏覽器需要檢查所有的元素,因為元素間的位置和大小是相互影響,導致整頁需要重再佈局一次,再一次,再合成一次

2.2. JS / CSS > Style > Paint > Composite

改變 畫(Paint) 的相關屬性,成本比較底。

修改的是畫 (Paint) 相關屬性,例如 background image, text color, 或 shadows,一些和佈局 (Layout) 獨立無關的改變,瀏覽器會略過佈局,由畫(paint)步驟開始更新頁面。

2.3. JS / CSS > Style > Composite

既不是佈局(Layout),又不是畫(Paint),就是最輕量。

像素化五步曲中,最後一步合成(Composite)的變動是最便宜。例如常常出現的頁面上下滾動和元件的動畫,大家最渴望見到的情況是,在滾動和動畫出現的生命週期中,影響到的屬性只有合成
瀏覧器既不需要更新佈局,又不需要畫一次。

Remark

visibility: hiddendisplay: none 的不同處。前者在畫面上佔有空間,被渲染成一個空的元素,不被看到;後者將會從Render Tree 中消失。

CSSOM & DOM trees

CSSOM 樹 和 DOM 樹的組合,成為渲染樹 (Render Tree),它是用來運算元素佈局 (Layout) 和像素化(Pixel Pipeline) 上色到屏幕,而且最優化這一系列的過程。

  • DOM Tree 和 CSSOM Tree 組合成 Render tree.
  • Render tree 只包含將會渲染的節點 (Nodes)
  • 佈局合成就會按照 Render Tree 的安排而動工

Reference

https://developers.google.com/web/fundamentals/performance/rendering/

https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction

--

--

Peter Chang
Peter Chang

No responses yet