国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript 工作原理之十一-渲染引擎及性能優化小技巧

RyanQ / 1771人閱讀

摘要:在中渲染樹中的每個節點即是一個渲染器或者渲染器對象。計算的樣式每個渲染器對象代表一個矩形區域通常是和一個節點的盒模型相對應。坐標系統是相對于根渲染器的。根渲染器的定位為和大小即為瀏覽器窗口的可視化部分比如。渲染器作廢其在屏幕上的矩形區域。

原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協議共享,BY Troland。

本系列持續更新中,Github 地址請查閱這里。

這是 JavaScript 工作原理的第十一章。

迄今為止,之前的 JavaScript 工作原理系列文章集中于關注 JavaScript 語言本身的功能,在瀏覽器中的執行情況,如何優化等等。

然而,當在構建網絡應用的時候,不僅僅只是編寫自己運行的 JavaScript 代碼。所編寫的 JavaScript 代碼與運行環境息息相關。理解 JavaScript 運行環境,它的運行原理以及其組成會讓你構建出更好的應用并且一旦讓應用程序運行于各種環境下的時候,讓你更加胸有成竹地應對潛在的問題。

那么,讓我們一探瀏覽器主要組件吧:

用戶界面: 包括地址欄,后退和前進按鈕,書簽菜單等等。本質上,這里包含了除顯示用戶所看到的網頁本身的窗口以外的瀏覽器的每個部分。

瀏覽器引擎: 處理用戶界面和渲染引擎的交互

渲染引擎: 負責顯示網頁。渲染引擎解析 HTML 和 CSS 并在屏幕上顯示解析的內容。

網絡: 使用各個平臺的不同實現所發起的諸如 XHR 請求的網絡調用,這些網絡調用是基于跨平臺的接口實現的。

UI 后端: 負責繪制諸如復選框和窗口的核心部件。它暴露出一個平臺無關的泛型接口。它底層使用操作系統 UI 方法。

JavaScript 引擎: 我們在之前的系列文章中有詳細介紹過。基本上,這是 JavaScript 代碼執行的地方。

數據存儲: 網絡應用可能需要本地存儲所有數據。支持的存儲機制類型包括 localStorage, indexDB, WebSQL 以及 FileSystem。

本文將專注介紹渲染引擎,因為它是用來處理 HTML 和 CSS 的解析和可視化的,而這些是大多數的 JavaScript 應用需要持續進行交互的方面。

渲染引擎概述

渲染引擎的主要職責即在瀏覽器屏幕上顯示請求的頁面。

渲染引擎可以顯示 HTML,XML 文檔以及圖片。如果使用額外的插件,就可以顯示諸如 PDF 的不同類型的文檔。

渲染引擎

與 JavaScript 引擎類似,不同瀏覽器也使用不同的渲染引擎。以下為比較流行的引擎:

Gecko-Firefox

WebKit-Safari

Blink-Chrome, Opera(從版本 15 開始)

渲染過程

渲染引擎從網絡層獲取到請求的文檔內容。

構建 DOM 樹

渲染引擎的第一步即解析 HTML 文檔和轉化解析的元素為 DOM 樹 上的實際 DOM 節點。

假設有如下的文本輸入框:


  
    
    
  
  
    

Hello, friend!

Smiley face

HTML 的 DOM 樹類似這樣:

基本上,每個元素是直接包含于其內的元素的父節點。然后依次類推。

構建 CSSOM 樹

CSSOM 即 CSS Object Model。當瀏覽器構建頁面的 DOM 樹的時候,它在 head 標簽部分遇到一個引用外部 theme.css 樣式表的 link 標簽。表示它可能需要樣式表來渲染頁面,于是便馬上分派一個請求來獲取樣式表。假設以下為 theme.css 文件內容:

body { 
  font-size: 16px;
}

p { 
  font-weight: bold; 
}

span { 
  color: red; 
}

p span { 
  display: none; 
}

img { 
  float: right; 
}

與 HTML 一樣,渲染引擎需要把 CSS 轉化為瀏覽器可以操作的東西-即 CSSOM。以下為 CSSOM 的大概模樣:

想知道為什么 CSSOM 是樹狀結構的嗎?當為頁面上的任意對象計算其最終的樣式集的時候,瀏覽器先把最為通用的樣式規則應用于該節點(比如,它是 body 的子節點,會先應用 body 的所有樣式)然后通過應用更為具體的樣式規則來遞歸重定義計算的樣式。

讓我們看下具體的例子吧。body 中的 span 標簽中的任何文字樣式為字體大小 16 像素且字體顏色為紅色。這些樣式繼承自 body 元素。p 元素的子元素 span 由于應用了更為具體的樣式從而不會顯示其內容(display:none)。

還有,請注意以上 CSSOM 樹并不完整而且只顯示了樣式表中指定的重寫樣式。每個瀏覽器提供了一份默認的樣式集即 『用戶代理樣式』- 這即當沒有提供任何樣式的時候的默認顯示樣式。我們的樣式只是簡單地重寫了這些默認樣式。

構建渲染樹

HTML 中的可視化指令和 CSSOM 樹的樣式數據結合起來創建渲染樹。

你可能為問渲染樹是什么?它是按順序構建可視化元素并顯示在屏幕上的樹。它是帶有相應的樣式的 HTML 的視覺表現。該樹旨在按正確的順序繪制內容。

在 Webkit 中渲染樹中的每個節點即是一個渲染器或者渲染器對象。

以下為以上的 DOM 和 CSSOM 樹合成的渲染器樹的大概模樣:

為了創建渲染樹,瀏覽器大概做了幾下幾件事:

從 DOM 樹的根節點開始,遍歷每個可見節點。一些節點是不可見的(比如,script 標簽,meta 標簽等等),然后會被忽略,因為它們并不會在渲染的輸出中顯示。一些節點通過樣式隱藏然后也會被忽略。比如以上例子中的 span 節點,因為為其顯式設置了 display: none 的樣式。

瀏覽器為每個可見節點應用相對應的 CSSOM 規則并應用這些樣式規則。

釋放出包含內容及其經過計算的樣式的可見節點。

可以瀏覽下 RenderObject 的源碼(Webkit 中):https://github.com/WebKit/web...

看一下這個類的一些核心構件吧:

class RenderObject : public CachedImageClient {
  // 重繪整個對象。當邊框顏色改變或者邊框樣式更改的時候調用。
  
  Node* node() const { ... }
  
  RenderStyle* style;  // 計算的樣式
  const RenderStyle& style() const;
  
  ...
}

每個渲染器對象代表一個矩形區域通常是和一個節點的 CSS 盒模型相對應。它包括諸如寬度,高度以及定位的幾何信息。

渲染樹布局

當創建了渲染器并且添加到渲染樹的時候,它并沒有定位和大小的信息。計算這些值即稱為布局。

HTML 使用了流式布局模型,意即大多數情況下可以一次性計算出渲染器的幾何信息。坐標系統是相對于根渲染器的。這里使用 Top 和 left 坐標。

布局是一個遞歸的過程-它從根渲染器開始進行渲染,根渲染器即 HTML 文檔的 html 元素。布局繼續通過一部分或者整個渲染器層級結構遞歸進行,為每個需要計算幾何信息的渲染器計算其信息。

根渲染器的定位為 0,0 和大小即為瀏覽器窗口的可視化部分(比如 viewport)。

進行布局的過程即計算出每個節點在屏幕上顯示的準確位置。

繪制渲染樹

該階段,遍歷渲染器樹然后調用渲染器的 paint() 方法來在屏幕上顯示其內容。

繪制可以是全局或增量式的(類似于布局):

全局-重繪整個樹。

增量-以某種方式只更改部分渲染器而不會影響到整顆樹。渲染器作廢其在屏幕上的矩形區域。這會導致操作系統把它看成是一個需要重繪的區域并生成一個 paint 事件。操作系統會智能地把幾個區域合并成一個以提升渲染性能。

總之,理解繪制是個漸進式的過程是很重要的。為了更好的交互體驗,渲染引擎會試圖盡快在屏幕上顯示內容。它不會等待所有的 HTML 結構解析完成才開始構建和布局渲染樹。會優先解析和顯示部分內容,與此同時持續處理從網絡接收的剩下的內容項。

腳本和樣式的處理順序

當解析器遇到

閱讀需要支付1元查看
<