您好,登錄后才能下訂單哦!
本篇內容介紹了“怎么理解web渲染引擎與前端優化”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
大家知道,大部分的 WEB 頁面依托瀏覽器呈現,而瀏覽器能夠將頁面展示出來,基本依賴于瀏覽器的內核,即渲染引擎。今天以 Chrome 瀏覽器的內核 WebKit(更確切是 WebKit 分支 Blink,以下統稱為 WebKit )為例,對渲染引擎如何展示頁面做個簡單、全面的了解。
瀏覽器的渲染引擎及其依賴模塊
渲染引擎主要是將 WEB 資源如 HTML、CSS、圖片、JavaScript等經過一系列加工,最終呈現出展示的圖像。渲染引擎主要包含了對這些資源解析的處理器,如 HTML 解釋器、CSS 解釋器、布局計算+繪圖工具、JavaScript 引擎等。為了更好地呈現渲染效果,渲染引擎還會依賴網絡棧、緩存機制、繪圖工具、硬件加速機制等。
瀏覽器的渲染過程
瀏覽器的渲染過程,主要包括兩大部分:網頁資源加載過程和渲染過程。
上圖將整個網頁渲染的過程做了大致的剖析。以下我們按照數據流向,逐一詳細剖析每個過程。
一、域名解析 DNS
當我們在瀏覽器中輸入 URL 后,瀏覽器首先會進行域名解析。一般情況下,一次 DNS 域名解析大概需要 60-120 ms,一次 TCP 的三次握手需要 1.5 個 RTT(round-trip time)。WebKit 的方案是 采用 DNS 預取技術和 TCP 預連接技術。
DNS 預取技術利用現有 DNS 機制,提前解析網頁中可能的網絡連接。即對用戶瀏覽網頁中存在的鏈接,用較少的 CPU 和網絡帶寬來解析這些鏈接的域名或 IP 地址;等用戶單擊鏈接時,就會節省時間~ 特別是域名解析慢的時候~
同樣,在地址欄輸入鏈接時,候選項也會被默默地執行 DNS 預取~。在 DNS 預取后,會預先建立 TCP 連接。
對此前端優化建議:
在頁面中指定預取域名:<link rel=”dns-prefetch” href=”http://this-is-a.com”>
大數據分析,推測用戶可能點擊的鏈接,提前預取。
減少頁面中的域名數量,可以直接減少DNS的請求。
二、SPDY 和 HTTP2
因為請求帶來的 TCP 三次握手的 1.5 RTT 延遲,Google 引入 SPDY,嘗試解決HTTP的延遲和安全性(HTTP 明文方式)問題。不過,SPDY 促使了 HTTP2.0 的誕生后,自己也不再更新,逐步退出。
SPDY 基于 SSL 之上,輕松兼容 HTTP 新老版本。其優勢如下:
多路復用。一個 TCP 連接傳輸多個資源。減少 TCP 連接成本。
不同資源,不同優先級。比如優先加載首屏。
Header 頭壓縮。減少傳送的字節數。SPDY 對 Header 壓縮率可高達 80%。
SPDY 開拓了 HTTP 新局面,秒殺我們太多的前端優化工作,從本質上提升了頁面加載速度。但我們前端優化的工作還是不能偏廢。向著繼續減少請求,減少 TCP 連接建立的路上,讓我們繼續。
合并資源,如 combo 合并 JavaScript 文件、CSS 文件,利用 sprite 合并圖片,圖片地圖等;
當頁面資源較小時,可直接放頁面中,如小圖可使用 Base64 編碼格式引入。甚至一些基礎樣式,或首屏依賴樣式,都可以放在頁面中;
資源壓縮技術。如 Gzip 等。主要是對響應數據的壓縮~
精簡 JavaScript 和 CSS 代碼。減少無用的空格。壓縮混淆~
避免鏈接重定向、避免錯誤的鏈接請求。建立多次鏈接、多次 DNS 解析,阻礙 DNS 預取技術。及時更新掉你頁面中沒有價值的鏈接吧。
三、資源加載
域名解析完,TCP 連接也建立起來后,資源加載器就開始工作了。
資源及資源加載器
資源包括:HTML、JavaScript、CSS 樣式表、圖片、SVG、字體文件、視頻音頻等。資源加載器有三種:
特定加載器,只加載某一種。如ImageLoader類。
緩存機制的資源加載器。特定加載器通過它查找是否有緩存資源,屬于 HTML 的文檔對象。
通用的資源加載器。在WebKit需要從網絡或文件系統獲取資源時使用。只負責獲取資源的數據,被所有特定資源加載器共享。
資源加載的過程
在 WebKit 中,資源都以 CachedResource 為基類,以 Cached 為前綴,體現了瀏覽器的緩存機制。即請求資源時,瀏覽器會先看緩存中有沒有這個資源,然后再決定是否向服務器發出請求。
這引出兩個問題,首先,緩存資源的生命周期。
瀏覽器緩存不會***增大,緩存池中的數據必然出現更替,WebKit 采用 LRU 最近最少使用算法更新緩存池數據。WebKit 遵循 HTTP 協議,當頁面刷新時,判斷資源是否在資源池。若存在,則附上該資源在本地的一些信息(如修改時間等),發送 HTTP 請求給服務器,服務器根據信息作出判斷,若資源沒更新則網絡狀態為 304,利用現有資源;否則執行資源加載過程。
其次,資源加載過程。
資源池中沒有該資源時,執行加載過程。WebKit 可以并行(多線程)下載普通資源和 JavaScript 資源。在當前主線程被阻塞時,WebKit 會啟動另一個線程去遍歷后邊的網頁,收集需要的資源 URL再發請求,避免阻塞。
基于資源加載,前端優化建議:
利用緩存機制,緩存常用且短時期內不會變更的資源,或給資源設置過期時間。
比如設置 ETag/Last-Modified 和 Expires/Cache-Control。
Expires/Cache-Control 兩者作用一致,指明資源有效期,如果本地緩存還在有效期內,瀏覽器直接使用本地緩存,不再發送請求。兩者同時配置時,Cache-Control 高于 Expires。配置 ETag/Last-Modified 后,瀏覽器再次訪問 URL 時,還會向服務器發送請求,確認文件是否已修改,沒修改則服務器返回304,瀏覽器直接從本地緩存獲取數據;修改過則服務器返回數據給瀏覽器。兩者同時配置,服務器會優先檢測 ETag,一致才會繼續檢測 Last-Modified。兩者同時配置,可以使服務器更準確的判斷瀏覽器是否已有需要的緩存數據。
ETag/Last-Modified 和 Expires/Cache-Control 兩對都設置時, Expires/Cache-Control 優先級更高。所以,只要本地緩存在有效期內,就不會發送請求。但頁面 F5 刷新和強刷時,緩存將失效。
鑒于資源下載中可能被阻塞,將 JavaScript 文件放置頁面下方。JavaScript 資源就是阻塞主線程的那個,而重建一個線程也是需要時間滴,所以把 JavaScript 扔***吧~ 但 JavaScript 資源并不影響之前資源的加載和 DOM 樹的構建。
四、從 URL 到 DOM 樹的構建
當我們拿到頁面所需的資源后,渲染引擎便啟動 HTML 解釋器,對獲取的資源進行解析處理。網頁代碼(字節流)經過詞法分析器解碼,再由語法分析器解釋成詞語 Token,并構建成節點 Node,直到最終構建成一棵 DOM 樹。
期間,當節點為 JavaScript 節點時,將啟動 JavaScript 引擎,這時將阻塞 DOM 樹的構建。因為 JavaScript 執行過程中, JavaScript 很可能會對 DOM 樹進行讀寫操作。直到 JavaScript 執行完畢, DOM 樹才會恢復構建。
其他資源并不影響 DOM 樹的構建。
在前端優化中,建議將 CSS 文件放在頁首,以便構建 DOM 樹;而將 JavaScript 文件盡量放在頁面下方,防止阻塞構建 DOM 樹;而 JavaScript 的 onload 事件里,不要寫太多影響首屏渲染的、操作 DOM 樹的 JavaScript 代碼。
另外強調一下:
DOMContentLoaded: DOM 樹構建完;
DOM 的onload事件: DOM 樹構建完且網頁依賴的資源都加載完了~
五、網頁排版過程:由 DOM 樹到構建 RenderLayer 樹
這一過程,就像是頁面的排版過程。它通過 CSS 樣式信息,對 DOM 樹進行排版,形成 RenderObject 樹及 RenderLayer 樹。
在 DOM 樹構建完成后,WebKit 為 DOM 樹節點構建 RenderObject 對象。WebKit 將根據盒模型計算節點的位置、大小等樣式信息(即布局計算或排版),并將這些信息保存到對應的 RenderObject 對象。
1. CSS解釋器
CSS解釋過程,是從 CSS 字符串經過 CSS 解釋器(CSSParser、CSSGrammer)處理后,變成渲染引擎的內部樣式規則表示的過程。樣式規則是解釋器的輸出結構,是樣式匹配的輸入數據。
具體過程:WebKit 在渲染元素時,CSS 解釋器獲取樣式信息,返回匹配好的結果樣式信息。每個元素可能需要匹配不同來源的規則,依次是用戶代理(瀏覽器)規則集合、用戶規則集合和HTML頁面中包含的自定義規則集合。三者匹配方式類似。
對于每個規則集合,先查找 ID 規則,檢查有無匹配的規則,然后依次檢查類型規則、標簽規則等。匹配好的規則,保存到匹配結果中。WebKit 對這些規則進行排序。對于元素需要的樣式屬性,WebKit 選擇從高優先級規則中選取,并將樣式屬性值返回。
2. 渲染基礎:RenderObject 樹
DOM 樹經過布局計算、CSS parse 后,將樣式信息存儲在 RenderObject 對象中,并構建成 RenderObject 樹。同時,WebKit 會根據網頁的層次結構創建 RenderLayer 樹,完成繪圖上下文。DOM 樹、Render 樹和繪圖上下文同時并存,直到頁面銷毀。
RenderObject 樹,基于 DOM 樹的一棵新樹,是布局計算和渲染等機制的基礎設施。
DOM 節點建立新的 RenderObject 對象的時機:
DOM 樹的 Document 節點。
DOM 樹的可視節點,如html、body、div 等。非可視節點如meta、head、script 等不創建。
為滿足 WebKit 處理,需要建立匿名 RenderObject 節點,它不對應于 DOM 樹的任何節點。如:匿名的 RenderBlock 節點。
DOM 樹的每個節點對象會遞歸檢查是否需要創建 RenderObject,并根據 DOM 節點類型創建 RenderObject 節點;動態加入的 DOM 元素,會相應的創建 RenderObject 節點。所有這些節點構成一棵 RenderObject 樹。
3. 渲染基礎:網頁層次和 RenderLayer 樹
在 HTML 頁面上,網頁分層展示。目的有兩個:1. 方便開發網頁、設置網頁的層次;2. 簡化 WebKit 渲染的邏輯。
在RenderObject 樹基礎上,WebKit 根據需要為其中的某些節點創建新的 RenderLayer 節點,并形成一棵 RenderLayer 樹。
RenderObject 節點建立新 RenderLayer 對象的時機:
DOM 樹的 Document 節點對應的 RenderView 節點。
DOM 樹的 Document 的子節點,即 HTML 節點對應的 RenderBlock 節點。
顯式的指定 CSS 位置的 RenderObject 節點。
有透明效果的 RenderObject 節點。
節點有溢出 overflow、alpha 或反射等效果的 RenderObject 節點。
使用Canvas 2D、3D (WebGL)技術的 RenderObject 節點。
Video 節點對應的 RenderObject 節點。
RenderLayer 節點的使用可以有效減少網頁結構的復雜程度,并在許多情況下能減少重新渲染的開銷。
4. 布局計算及重繪時機
CSS 盒模型,是布局計算的基礎;渲染引擎用來確定如何排版元素、及元素間的位置關系。
布局計算,是針對 RenderObject 樹及其子樹的計算,是一種遞歸計算,其節點信息需要先計算其子節點的位置、大小等信息。RenderObject 對象會將計算結果存儲,等待渲染時機。
每個元素會實現自己的 layout。
頁面元素定義了寬高,則按自定義寬高確定元素大小。
文本節點等內聯元素,需要結合字號大小、文字多少確定寬高。
頁面元素確定的寬高超過了布局容器包含塊提供的寬高,同時 overflow 為 visible 或 auto,WebKit 則提供滾動條保證可顯示所有內容。
一般頁面元素的寬高是在布局時通過計算得來。除非網頁定義了頁面元素的寬高。
重繪時機:只要樣式發生變化,就重新計算。
***打開頁面,瀏覽器設置網頁的可視區域,并調用計算布局的方法。可視區域改變時,網頁包含塊的大小也會改變,WebKit 需要重新計算布局。
網頁的動畫會觸發布局計算。動畫可能改變樣式屬性。
JavaScript 通過 CSSOM(CSS 對象模型) 直接修改樣式,會觸發 WebKit 重新計算布局。
用戶交互,如滾動網頁。
前端優化建議,因布局計算耗時間,一旦布局發生變化,WebKit 就需要后面的重新繪制操作。SO,減少樣式的變動~減少重繪~利用 CSS3 新功能(如 CSS3 變形 translate、scale、rotate 等方法,過渡 transition 方法等)可有效提高網頁的渲染效率。
六、 網頁渲染過程:由 RenderLayer 樹到最終的圖像
在上一個過程,網頁完成了 DOM 樹到 RenderLayer 樹的布局計算和排版處理。接下來,由渲染引擎(一般是繪圖類工具)完成對 RenderLayer 樹的繪制,并最終形成圖像,展示給用戶。
1. 繪圖上下文
繪圖上下文,所有的繪圖操作都是在該上下文中進行的。它是一個與平臺無關的抽象類,它將每個繪圖操作橋接到不同的繪圖具體實現類。
2D 繪圖上下文:
提供基本繪圖單元的繪制接口及設置繪圖的樣式。
繪圖接口包括:畫點、畫線、畫圖、畫多邊形、畫文字等。繪圖樣式包括顏色、線寬、字號、漸變等。
CPU 來完成 2D 操作。或用 3D 圖形接口( OpenGL )完成。
3D 繪圖上下文:支持 CSS3D、WebGL 等。
使用 3D 圖形接口(OpenGL、Direct3D 等)
2. 渲染方式
軟件渲染:CPU。通常渲染的結果是一個位圖,繪制每一層時都使用該位圖,區別在于位置可能不同,每一層按從后到前的順序。沒必要為每層分配一個位圖,沒必要合成。
缺點:對 HTML5 新技術,
能力不足,CSS3D、WebGL;
性能不好,如視頻、Canvas 2D;
使用率下降,特別是移動端。
優勢:對更新區域處理,軟件渲染可能只需要計算極小區域,硬件則需要繪制其中一層或多層,再合成。硬件代價大。
硬件加速渲染:GPU 必須有合成的步驟。分層繪制+合成。不過對于更新區域,如果只是在一個層,硬件可能會更快。
WebKit 的實現方式:
使用合適的網頁分層技術、減少重新計算的布局和繪圖。
使用CSS 3D 變形和動畫技術。CSS 3D 變形技術,能讓瀏覽器僅使用合成器合成所有層就可以達到動畫效果。不需要布局計算和重繪~
前端優化建議:
減少重繪:因為重繪是要計算布局、繪圖、合成三個階段。其中計算布局和繪圖比較費時,合成要少。
“怎么理解web渲染引擎與前端優化”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。