阿里雲最近在作活動,低至2折,有興趣能夠看看:
https://promotion.aliyun.com/...
爲了保證的可讀性,本文采用意譯而非直譯。javascript
這是專門探索 JavaScript 及其所構建的組件的系列文章的第11篇。css
想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等着你!html
若是你錯過了前面的章節,能夠在這裏找到它們:前端
當你構建 Web 應用程序時,你不僅是編寫單獨運行的 JavaScript 代碼,你編寫的 JavaScript 正在與環境進行交互。瞭解這種環境,它的工做原理以及它的組,這些有助於你夠構建更好的應用程序,併爲應用程序發佈後可能出現的潛在問題作好充分準備。java
瀏覽器的主要組件包括:git
在這篇文章中,將重點討論渲染引擎,由於它處理 HTML 和 CSS 的解析和可視化,這是大多數 JavaScript 應用程序常常與之交互的東西。github
渲染引擎的職責就是渲染,即在瀏覽器窗口中顯示所請求的內容。web
渲染引擎能夠顯示 HTML 和 XML 文檔和圖像。若是使用其餘插件,渲染引擎還能夠顯示不一樣類型的文檔,如 PDF。編程
與 JavaScript 引擎相似,不一樣的瀏覽器也使用不一樣的渲染引擎。如下是一些最受歡迎的:segmentfault
Firefox、Chrome 和 Safari 是基於兩種渲染引擎構建的,Firefox 使用 Geoko——Mozilla 自主研發的渲染引擎,Safari 和 Chrome 都使用 Webkit。Blink 是 Chrome 基於 WebKit的自主渲染引擎。
渲染引擎從網絡層接收所請求文檔的內容。
解析 HTML 以構建 Dom 樹 -> 構建 Render 樹 -> 佈局 Render 樹 -> 繪製 Render 樹
渲染現引擎的第一步是解析 HTML文檔,並將解析後的元素轉換爲 DOM 樹中的實際 DOM 節點。
假若有以下 Html 結構
<html> <head> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="theme.css"> </head> <body> <p> Hello, <span> friend! </span> </p> <div> <img src="smiley.gif" alt="Smiley face" height="42" width="42"> </div> </body> </html>
對應的 DOM 樹以下:
基本上,每一個元素都表示爲全部元素的父節點,這些元素直接包含在元素中。
CSSOM 指的是 CSS 對象模型。 當瀏覽器構建頁面的 DOM 時,它在 head
標籤下如遇到了一個 link
標記且引用了外部 theme.css CSS 樣式表。 瀏覽器預計可能須要該資源來呈現頁面,它會當即發送請求。 假設 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
元素繼承而來的。 若是一個 span
元素是一個 p
元素的子元素,那麼它的內容就不會被顯示,由於它被應用了更具體的樣式(display: none)。
另請注意,上面的樹不是完整的 CSSOM 樹,只顯示咱們決定在樣式表中覆蓋的樣式。 每一個瀏覽器都提供一組默認樣式,也稱爲「user agent stylesheet」。這是咱們在未明確指定任何樣式時看到的樣式,咱們的樣式會覆蓋這些默認值。
不一樣瀏覽器對於相同元素的默認樣式並不一致,這也是爲何咱們在 CSS 的最開始要寫 *{padding:0;marging:0};
,也就是咱們要重置CSS默認樣式的。
CSSOM 樹和 DOM 樹鏈接在一塊兒造成一個 render tree,渲染樹用來計算可見元素的佈局而且做爲將像素渲染到屏幕上的過程的輸入。
渲染樹中的每一個節點在 Webkit 中稱爲渲染器或渲染對象。
收下是上面 DOM 和 CSSOM 樹的渲染器樹的樣子:
爲了構建渲染樹,瀏覽器大體執行如下操做:
從 DOM 樹根節點開始,遍歷每個可見的節點
display:none
「visibility:hidden」 和
「display:none」 之間的不一樣,
「visibility:hidden」 將元素設置爲不可見,可是一樣在佈局上佔領必定空間(例如,它會被渲染成爲空盒子),可是
「display:none」 的元素是將節點從整個
render tree
中移除,因此不是佈局中的一部分 。
你能夠在這裏查看 RenderObject 的源代碼(在 WebKit 中):
https://github.com/WebKit/web...
咱們來看看這個類的一些核心內容:
每一個渲染器表明一個矩形區域,一般對應於一個節點的 CSS 盒模型。它包含幾何信息,例如寬度、高度和位置。
建立渲染器並將其添加到樹中時,它沒有位置和大小,計算這些值稱爲佈局。
HTML使用基於流的佈局模型,這意味着大多數時間它能夠一次性計算幾何圖形。座標系統相對於根渲染器,使用左上原點座標。
佈局是一個遞歸過程 - 它從根渲染器開始,它對應於 HTML 文檔的 <html>
元素。 佈局以遞歸方式繼續經過部件或整個渲染器層次結構,爲每一個須要它的渲染器計算幾何信息。
根渲染器的位置爲0,0
,其尺寸與瀏覽器窗口的可見部分(即viewport)的大小相同。開始佈局過程意味着給每一個節點在屏幕上應該出現的確切座標。
在此繪製,遍歷渲染器樹並調用渲染器的 paint()
方法以在屏幕上顯示內容。
繪圖能夠是全局的或增量式的(與佈局相似):
paint
事件的區域。 操做系統經過將多個區域合併爲一個來智能完成。總的來講,重要的中要理解繪圖是一個漸進的過程。爲了更好的用戶體驗,渲染引擎將盡量快地在屏幕上顯示內容。它不會等到解析完全部 HTML 後纔開始構建和佈局渲染樹,而是解析和顯示部份內容,同時繼續處理來自網絡的其他內容項。
當解析器到達 <script>
標記時,將當即解析並執行腳本。文檔的解析將暫停,直到執行腳本爲止。這意味着這個過程是同步的。
若是腳本是外部的,那麼首先必須從網絡中獲取它(也是同步的)。全部解析都中止,直到獲取完成。HTML5 新加了async 或 defer 屬性,將腳本標記爲異步的,以便由不一樣的線程解析和執行。
若是你想優化本身的應用,則須要關注五個主要方面,這些是你本身能夠控制的:
JavaScript 常常觸發瀏覽器中的視覺變化,構建 SPA 時更是如此。
如下是一些優化 JavaScript 渲染技巧:
setTimeout
或 setInterval
進行可視更新。 這些將在幀中的某個點調用 callback
,可能在最後。咱們想要作的是在幀開始時觸發視覺變化而不是錯過它。requestAnimationFrame
, setTimeout
, setInterval
中運行它們。經過添加和刪除元素,更改屬性等來修改 DOM 將使瀏覽器從新計算元素樣式,而且在許多狀況下,從新計算整個頁面的佈局或至少部分佈局。
要優化渲染,考慮如下事項:
* 減小必須進行樣式計算的元素的數量。本質上,直接對一些元素進行樣式更改,而不是使整個頁面無效。
瀏覽器的佈局從新計算可能很是繁重。 考慮如下優化:
box.offsetHeight
,那就不成問題了。可是,若是你在訪問 box
以前更改了它的樣式(例如,經過動態地向元素添加一些 CSS 類),瀏覽器必須先應用樣式更改並執行佈局過程,這是很是耗時和耗費資源的,因此儘量避免。這一般是全部任務中運行時間最長的,所以儘量避免這種狀況很是重要。 如下是咱們能夠作的事情:
原文:
https://blog.sessionstack.com...
代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
你的點贊是我持續分享好東西的動力,歡迎點贊!
乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。
https://github.com/qq44924588...
我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!
關注公衆號,後臺回覆福利,便可看到福利,你懂的。