成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

JavaScript是如何工作的:渲染引擎和優(yōu)化其性能的技巧

新聞 前端
當你構(gòu)建 Web 應(yīng)用程序時,你不只是編寫單獨運行的 JavaScript 代碼,你編寫的 JavaScript 正在與環(huán)境進行交互。

當你構(gòu)建 Web 應(yīng)用程序時,你不只是編寫單獨運行的 JavaScript 代碼,你編寫的 JavaScript 正在與環(huán)境進行交互。了解這種環(huán)境,它的工作原理以及它的組,這些有助于你夠構(gòu)建更好的應(yīng)用程序,并為應(yīng)用程序發(fā)布后可能出現(xiàn)的潛在問題做好充分準備。

[[255445]]

瀏覽器的主要組件包括:

  • 用戶界面 (User interface): 包括地址欄、后退/前進按鈕、書簽?zāi)夸浀龋簿褪悄闼吹降某擞脕盹@示你所請求頁面的主窗口之外的其他部分
  • 瀏覽器引擎 (Browser engine): 用來查詢及操作渲染引擎的接口
  • 渲染引擎 (Rendering engine): 用來顯示請求的內(nèi)容,例如,如果請求內(nèi)容為 html,它負責解析 html 及 css,并將解析后的結(jié)果顯示出來
  • 網(wǎng)絡(luò) (Networking): 用來完成網(wǎng)絡(luò)調(diào)用,例如http請求,它具有平臺無關(guān)的接口,可以在不同平臺上工作
  • UI 后端 (UI backend): 用來繪制類似組合選擇框及對話框等基本組件,具有不特定于某個平臺的通用接口,底層使用操作系統(tǒng)的用戶接口
  • JS 解釋器 (JavaScript engine): 用來解釋執(zhí)行JS代碼
  • 數(shù)據(jù)存儲 (Data persistence): 屬于持久層,瀏覽器需要在硬盤中保存類似 cookie 的各種數(shù)據(jù),HTML5定義了 Web Database 技術(shù),這是一種輕量級完整的客戶端存儲技術(shù),支持的存儲機制類型包括 localStorage 、 indexDB 、 WebSQL 和 FileSystem 。

在這篇文章中,將重點討論渲染引擎,因為它處理 HTML 和 CSS 的解析和可視化,這是大多數(shù) JavaScript 應(yīng)用程序經(jīng)常與之交互的東西。

渲染引擎概述

渲染引擎的職責就是渲染,即在瀏覽器窗口中顯示所請求的內(nèi)容。

渲染引擎可以顯示 HTML 和 XML 文檔和圖像。如果使用其他插件,渲染引擎還可以顯示不同類型的文檔,如 PDF。

渲染引擎 (Rendering engines)

與 JavaScript 引擎類似,不同的瀏覽器也使用不同的渲染引擎。以下是一些最受歡迎的:

  • Gecko — Firefox
  • WebKit — Safari
  • Blink — Chrome,Opera (版本 15 之后)

Firefox、Chrome 和 Safari 是基于兩種渲染引擎構(gòu)建的,F(xiàn)irefox 使用 Geoko——Mozilla 自主研發(fā)的渲染引擎,Safari 和 Chrome 都使用 Webkit。Blink 是 Chrome 基于 WebKit的自主渲染引擎。

渲染的過程

渲染引擎從網(wǎng)絡(luò)層接收所請求文檔的內(nèi)容。

[[255446]]

解析 HTML 以構(gòu)建 Dom 樹 -> 構(gòu)建 Render 樹 -> 布局 Render 樹 -> 繪制 Render 樹

構(gòu)建 Dom 樹

渲染現(xiàn)引擎的第一步是解析 HTML文檔,并將解析后的元素轉(zhuǎn)換為 DOM 樹 中的實際 DOM 節(jié)點。

假如有如下 Html 結(jié)構(gòu)

  1. <html> 
  2.   <head> 
  3.     <meta charset="UTF-8"
  4.     <link rel="stylesheet" type="text/css" href="theme.css"
  5.   </head> 
  6.   <body> 
  7.     <p> Hello, <span> friend! </span> </p> 
  8.     <div>  
  9.       <img src="smiley.gif" alt="Smiley face" height="42" width="42"
  10.     </div> 
  11.   </body> 
  12. </html> 

對應(yīng)的 DOM樹如下:

[[255447]]

基本上,每個元素都表示為所有元素的父節(jié)點,這些元素直接包含在元素中。

構(gòu)建 CSSOM

CSSOM 指的是 CSS 對象模型 。 當瀏覽器構(gòu)建頁面的 DOM 時,它在 head 標簽下如遇到了一個 link 標記且引用了外部 theme.css CSS 樣式表。 瀏覽器預(yù)計可能需要該資源來呈現(xiàn)頁面,它會立即發(fā)送請求。 假設(shè) theme.css 文件內(nèi)容如下:

  1. body {  
  2.   font-size: 16px; 
  3.  
  4. p {  
  5.   font-weight: bold;  
  6.  
  7. span {  
  8.   color: red;  
  9.  
  10. p span {  
  11.   display: none;  
  12.  
  13. img {  
  14.   float: right;  

與 HTML一樣,渲染引擎需要將 CSS 轉(zhuǎn)換成瀏覽器可以使用的東西—— CSSOM。CSSOM 結(jié)構(gòu)如下:

[[255448]]

你想知道為什么 CSSOM 是一個樹形結(jié)構(gòu)? 在為頁面上的任何對象計算最終樣式集時,瀏覽器以適用于該節(jié)點的最常規(guī)規(guī)則開始(例如,如果它是 body 元素的子元素,則應(yīng)用所有 body 樣式),然后遞歸地細化,通過應(yīng)用更具體的規(guī)則來計算樣式。

來看看具體的例子。包含在 body 元素內(nèi)的 span 標簽中的任何文本的字體大小均為 16 像素,并且為紅色。這些樣式是從 body 元素繼承而來的。 如果一個 span 元素是一個 p 元素的子元素,那么它的內(nèi)容就不會被顯示,因為它被應(yīng)用了更具體的樣式(display: none)。

另請注意,上面的樹不是完整的 CSSOM 樹,只顯示我們決定在樣式表中覆蓋的樣式。 每個瀏覽器都提供一組默認樣式,也稱為 “user agent stylesheet” 。這是我們在未明確指定任何樣式時看到的樣式,我們的樣式會覆蓋這些默認值。

[[255449]]

不同瀏覽器對于相同元素的默認樣式并不一致,這也是為什么我們在 CSS 的最開始要寫 *{padding:0;marging:0}; ,也就是我們要重置CSS默認樣式的。

構(gòu)建渲染樹

CSSOM 樹和 DOM 樹連接在一起形成一個 render tree,渲染樹用來計算可見元素的布局并且作為將像素渲染到屏幕上的過程的輸入。

  • DOM 樹和 CSSOM 樹連接在一起形成 render tree .
  • render tree 只包含了用于渲染頁面的節(jié)點
  • 布局計算了每一個對象的準確的位置以及大小
  • 繪畫是最后一步,繪畫要求利用 render tree 來將像素顯示到屏幕上

渲染樹中的每個節(jié)點在 Webkit 中稱為渲染器或渲染對象。

收下是上面 DOM 和 CSSOM 樹的渲染器樹的樣子:

[[255450]]

為了構(gòu)建渲染樹,瀏覽器大致執(zhí)行以下操作:

  • 從 DOM 樹根節(jié)點開始,遍歷每一個可見的節(jié)點

  1. display:none 
  • 對每一個可見的節(jié)點,找到合適的匹配的CSSOM規(guī)則,并且應(yīng)用樣式
  • 顯示可見節(jié)點(節(jié)點包括內(nèi)容和被計算的樣式)

“visibility:hidden” 和 “display:none” 之間的不同, “visibility:hidden” 將元素設(shè)置為不可見,但是同樣在布局上占領(lǐng)一定空間(例如,它會被渲染成為空盒子),但是 “display:none” 的元素是將節(jié)點從整個 render tree 中移除,所以不是布局中的一部分 。

你可以在這里查看 RenderObject 的源代碼(在 WebKit 中):

https://github.com/WebKit/web...

我們來看看這個類的一些核心內(nèi)容:

[[255451]]

每個渲染器代表一個矩形區(qū)域,通常對應(yīng)于一個節(jié)點的 CSS 盒模型。它包含幾何信息,例如寬度、高度和位置。

渲染樹的布局

創(chuàng)建渲染器并將其添加到樹中時,它沒有位置和大小,計算這些值稱為布局。

HTML使用基于流的布局模型,這意味著大多數(shù)時間它可以一次性計算幾何圖形。坐標系統(tǒng)相對于根渲染器,使用左上原點坐標。

布局是一個遞歸過程 - 它從根渲染器開始,它對應(yīng)于 HTML 文檔的 <html> 元素。 布局以遞歸方式繼續(xù)通過部件或整個渲染器層次結(jié)構(gòu),為每個需要它的渲染器計算幾何信息。

根渲染器的位置為 0,0 ,其尺寸與瀏覽器窗口的可見部分(即viewport)的大小相同。開始布局過程意味著給每個節(jié)點在屏幕上應(yīng)該出現(xiàn)的確切坐標。

繪制渲染樹

在此繪制,遍歷渲染器樹并調(diào)用渲染器的 paint() 方法以在屏幕上顯示內(nèi)容。

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

  • 全局 — 整棵樹被重繪
  • 增量式 — 只有一些渲染器以不影響整個樹的方式改變。 渲染器使其在屏幕上的矩形無效,這會導(dǎo)致操作系統(tǒng)將其視為需要重新繪制并生成繪 paint 事件的區(qū)域。 操作系統(tǒng)通過將多個區(qū)域合并為一個來智能完成。

總的來說,重要的中要理解繪圖是一個漸進的過程。為了更好的用戶體驗,渲染引擎將盡可能快地在屏幕上顯示內(nèi)容。它不會等到解析完所有 HTML 后才開始構(gòu)建和布局渲染樹,而是解析和顯示部分內(nèi)容,同時繼續(xù)處理來自網(wǎng)絡(luò)的其余內(nèi)容項。

處理腳本和樣式表的順序

當解析器到達 <script> 標記時,將立即解析并執(zhí)行腳本。文檔的解析將暫停,直到執(zhí)行腳本為止。這意味著這個過程是 同步的 。

如果腳本是外部的,那么首先必須從網(wǎng)絡(luò)中獲取它(也是同步的)。所有解析都停止,直到獲取完成。HTML5 新加了async 或 defer 屬性,將腳本標記為異步的,以便由不同的線程解析和執(zhí)行。

優(yōu)化渲染性能

如果你想優(yōu)化自己的應(yīng)用,則需要關(guān)注五個主要方面,這些是你自己可以控制的:

  1. JavaScript — 在之前的文章中,討論了如果編寫優(yōu)化代碼的主題抱包括如果編寫代碼才不會阻止UI,和提高內(nèi)存利用等等。在渲染時,需要考慮 JavaScript 代碼與頁面 上DOM 素交互的方式。 JavaScript 可以在 UI中創(chuàng)建大量更改,尤其是在 SPA 中。
  2. 樣式計算 — 這是根據(jù)匹配選擇器確定哪個 CSS 規(guī)則適用于哪個元素的過程。 定義規(guī)則后,將應(yīng)用它們并計算每個元素的最終樣式。
  3. 布局 — 一旦瀏覽器知道哪些規(guī)則適用于某個元素,它就可以開始計算后者占用多少空間以及它在瀏覽器屏幕上的位置。Web 的布局模型定義了一個元素可以影響其他元素。例如,<body> 的寬度會影響其子元素的寬度,等等。這意味著布局過程是計算密集型的,該繪圖是在多個圖層完成的。
  4. 繪圖 —— 這是實際像素被填充的地方,這個過程包括繪制文本、顏色、圖像、邊框、陰影等——每個元素的每個可視部分。
  5. 合成 — 由于頁面部分可能被繪制成多個層,因此它們需要以正確的順序繪制到屏幕上,以便頁面渲染正確。這是非常重要的,特別是對于重疊的元素。

優(yōu)化你的 JavaScript

JavaScript 經(jīng)常觸發(fā)瀏覽器中的視覺變化,構(gòu)建 SPA 時更是如此。

以下是一些優(yōu)化 JavaScript 渲染技巧:

  • 避免使用 setTimeout 或 setInterval 進行可視更新。 這些將在幀中的某個點調(diào)用 callback,可能在最后。我們想要做的是在幀開始時觸發(fā)視覺變化而不是錯過它。
  • 如之前文章 所述,將長時間運行的 JavaScript 計算轉(zhuǎn)移到 Web Workers。
  • 使用微任務(wù)在多個幀中變更 DOM。這是在任務(wù)需要訪問 DOM 時使用的, Web Worker 無法訪問 DOM。這基本上意味著你要把一個大任務(wù)分解成更小的任務(wù),然后根據(jù)任務(wù)的性質(zhì)在 requestAnimationFrame , setTimeout , setInterval 中運行它們。

優(yōu)化你的 CSS

通過添加和刪除元素,更改屬性等來修改 DOM 將使瀏覽器重新計算元素樣式,并且在許多情況下,重新計算整個頁面的布局或至少部分布局。

要優(yōu)化渲染,考慮以下事項:

  • 減少選擇器的復(fù)雜性,與構(gòu)造樣式本身的其他工作相比,選擇器復(fù)雜性可以占用計算元素樣式所需時間的50%以上。

*減少必須進行樣式計算的元素的數(shù)量。本質(zhì)上,直接對一些元素進行樣式更改,而不是使整個頁面無效。

優(yōu)化布局

瀏覽器的布局重新計算可能非常繁重。 考慮以下優(yōu)化:

  • 盡可能減少布局的數(shù)量。當你更改樣式時,瀏覽器會檢查是否有任何更改需要重新計算布局。對寬度、高度、左、頂?shù)葘傩缘母模约巴ǔEc幾何相關(guān)的屬性的更改,都需要布局。所以,盡量避免改變它們。
  • 盡量使用 flexbox 而不是老的布局模型。它運行速度更快,可為你的應(yīng)用程序創(chuàng)造巨大的性能優(yōu)勢。
  • 避免強制同步布局。需要記住的是,在 JavaScript 運行時,前一幀中的所有舊布局值都是已知的,可以查詢。如果你訪問 box.offsetHeight ,那就不成問題了。但是,如果你在訪問 box 之前更改了它的樣式(例如,通過動態(tài)地向元素添加一些 CSS 類),瀏覽器必須先應(yīng)用樣式更改并執(zhí)行布局過程,這是非常耗時和耗費資源的,所以盡可能避免。

優(yōu)化繪圖

這通常是所有任務(wù)中運行時間最長的,因此盡可能避免這種情況非常重要。 以下是我們可以做的事情:

  • 除了變換(transform)和透明度之外,改變其他任何屬性都會觸發(fā)重新繪圖,請謹慎使用。
  • 如果觸發(fā)了布局,那也會觸發(fā)繪圖,因為更改布局會導(dǎo)致元素的視覺效果也改變。
  • 通過圖層提升和動畫編排來減少重繪區(qū)域。
責任編輯:張燕妮 來源: segmentfault
相關(guān)推薦

2024-09-26 08:36:11

JavaScript性能優(yōu)化

2018-12-13 14:10:37

JavaScript調(diào)用堆棧前端

2022-02-25 23:46:54

JavaScript網(wǎng)站開發(fā)

2009-06-10 22:00:57

JavaScript腳

2009-06-11 17:15:23

JavaScript性

2022-04-27 10:35:27

邊緣渲染前端

2013-09-04 14:22:59

JavaScript性能優(yōu)化

2019-08-21 10:53:29

.NET性能優(yōu)化

2019-04-17 13:48:19

JavaScript前端傳遞

2021-02-01 08:36:19

JS引擎V8

2022-05-18 08:00:00

JavaScriptFetch數(shù)據(jù)

2013-11-20 13:47:43

瀏覽器渲染引擎

2020-10-30 09:00:00

JavaScriptJavaScript引前端

2011-09-29 09:50:44

JavaScript

2020-12-17 07:52:38

JavaScript

2016-12-08 10:57:08

渲染引擎前端優(yōu)化

2009-11-27 13:24:20

PHP代碼性能優(yōu)化

2010-07-26 16:35:34

Perl性能

2022-10-09 13:36:44

接口性能優(yōu)化

2024-01-22 13:16:00

接口性能優(yōu)化本地緩存
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 狠狠干天天干 | 久久免费精品视频 | 日韩黄 | 日韩av一二三区 | 久久精品国产a三级三级三级 | h在线| 国产一区二区高清在线 | 国产精品毛片av一区 | 欧美精品在线一区二区三区 | 中文字幕久久久 | 毛片国产| 在线免费观看成年人视频 | 国产精品中文字幕在线观看 | 毛片一级片 | 久久久久国产 | 亚洲精品在线看 | 久久久av | 中国黄色毛片视频 | 视频一区二区三区在线观看 | 成人一区二区三区在线观看 | 日日干日日操 | 超碰电影| 欧美精品91 | 国产98色在线| 免费视频二区 | 国产日韩精品一区 | 欧洲精品在线观看 | 欧美日韩国产一区二区三区 | 福利片在线看 | 在线视频久久 | 国产免费一区二区三区 | 精品免费视频一区二区 | 成人亚洲视频 | 久久亚洲一区二区三区四区 | 丁香久久| 国产aa | 国产视频一区二区 | 一级片免费视频 | 九色国产 | 亚洲成人一区二区 | 精品视频免费 |