日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > HTML >内容正文

HTML

前端浏览器渲染原理及优化

發(fā)布時(shí)間:2024/1/1 HTML 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前端浏览器渲染原理及优化 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 一.瀏覽器組成
      • 1. 對(duì)瀏覽器內(nèi)核的理解
      • 2. 瀏覽器的主要組成部分
    • 二、瀏覽器渲染原理
      • 1.瀏覽器的渲染過(guò)程
          • 步驟一:
          • 步驟二:
          • 步驟三:
          • 步驟四:
          • 步驟五:
      • 2.相關(guān)概念
          • ①重排(更新元素的幾何屬性)
          • ②重繪(更細(xì)元素的繪制屬性)
          • ③直接合成階段
    • 三.瀏覽器渲染優(yōu)化
      • **(1)針對(duì)JavaScript:**
      • **(2)針對(duì)CSS:**
      • **(3)針對(duì)DOM樹(shù)、CSSOM樹(shù):**
      • **(4)減少回流與重繪:**

一.瀏覽器組成

瀏覽器的主要功能是將用戶選擇的 web 資源呈現(xiàn)出來(lái),它需要從服務(wù)器請(qǐng)求資源,并將其顯示在瀏覽器窗口中,資源的格式通常是 HTML,也包括 PDF、image 及其他格式。用戶用 URI(Uniform Resource Identifier 統(tǒng)一資源標(biāo)識(shí)符)來(lái)指定所請(qǐng)求資源的位置。

1. 對(duì)瀏覽器內(nèi)核的理解

瀏覽器內(nèi)核主要分成兩部分:

  • 渲染引擎的職責(zé)就是渲染,即在瀏覽器窗口中顯示所請(qǐng)求的內(nèi)容。默認(rèn)情況下,渲染引擎可以顯示 html、xml 文檔及圖片,它也可以借助插件顯示其他類型數(shù)據(jù),例如使用 PDF 閱讀器插件,可以顯示 PDF 格式。
  • JS 引擎:解析和執(zhí)行 javascript 來(lái)實(shí)現(xiàn)網(wǎng)頁(yè)的動(dòng)態(tài)效果。

最開(kāi)始渲染引擎和 JS 引擎并沒(méi)有區(qū)分的很明確,后來(lái) JS 引擎越來(lái)越獨(dú)立,內(nèi)核就傾向于只指渲染引擎。

2. 瀏覽器的主要組成部分

  • ?戶界? - 包括地址欄、前進(jìn)/后退按鈕、書簽菜單等。除了瀏覽器主窗?顯示的您請(qǐng)求的??外,其他顯示的各個(gè)部分都屬于?戶界?。
  • 瀏覽器引擎 - 在?戶界?和呈現(xiàn)引擎之間傳送指令。
  • 呈現(xiàn)引擎 - 負(fù)責(zé)顯示請(qǐng)求的內(nèi)容。如果請(qǐng)求的內(nèi)容是 HTML,它就負(fù)責(zé)解析 HTML 和 CSS 內(nèi)容,并將解析后的內(nèi)容顯示在屏幕上。
  • ?絡(luò) - ?于?絡(luò)調(diào)?,?如 HTTP 請(qǐng)求。其接?與平臺(tái)?關(guān),并為所有平臺(tái)提供底層實(shí)現(xiàn)。
  • ?戶界?后端 - ?于繪制基本的窗??部件,?如組合框和窗?。其公開(kāi)了與平臺(tái)?關(guān)的通?接?,?在底層使?操作系統(tǒng)的?戶界??法。
  • JavaScript 解釋器。?于解析和執(zhí)? JavaScript 代碼。
  • 數(shù)據(jù)存儲(chǔ) - 這是持久層。瀏覽器需要在硬盤上保存各種數(shù)據(jù),例如 Cookie。新的 HTML 規(guī)范 (HTML5) 定義了“?絡(luò)數(shù)據(jù)庫(kù)”,這是?個(gè)完整(但是輕便)的瀏覽器內(nèi)數(shù)據(jù)庫(kù)。

值得注意的是,和?多數(shù)瀏覽器不同,Chrome 瀏覽器的每個(gè)標(biāo)簽?都分別對(duì)應(yīng)?個(gè)呈現(xiàn)引擎實(shí)例。每個(gè)標(biāo)簽?都是?個(gè)獨(dú)?的進(jìn)程。

二、瀏覽器渲染原理

1.瀏覽器的渲染過(guò)程

瀏覽器渲染主要有以下步驟:

步驟一:
  • 首先解析收到的文檔,根據(jù)文檔定義構(gòu)建一棵 DOM 樹(shù),DOM 樹(shù)是由 DOM 元素及屬性節(jié)點(diǎn)組成的。

步驟二:
  • 然后對(duì) CSS 進(jìn)行解析,生成 CSSOM 規(guī)則樹(shù)。

? 1、把css轉(zhuǎn)換為瀏覽器內(nèi)容理解的結(jié)構(gòu)

? 當(dāng)渲染引擎接收到CSS文本的時(shí),會(huì)執(zhí)行一個(gè)轉(zhuǎn)換操作,將css文本轉(zhuǎn)換為瀏覽器可以理解的結(jié)構(gòu)–styleSheets。

? 2、轉(zhuǎn)換樣式表中的屬性值,使其標(biāo)準(zhǔn)化

? 什么是標(biāo)準(zhǔn)化:

body { font-size: 2em } p {color:blue;} span {display: none} div {font-weight: bold} div p {color:green;} div {color:red; }

可以看到上面的 CSS 文本中有很多屬性值,如 2em、blue、bold,這些類型數(shù)值不容易被渲染引擎理解,所以需要將所有值轉(zhuǎn)換為渲染引擎容易理解的、標(biāo)準(zhǔn)化的計(jì)算值,這個(gè)過(guò)程就是屬性值標(biāo)準(zhǔn)化。

? 3、計(jì)算出DOM樹(shù)中每一個(gè)節(jié)點(diǎn)的具體樣式

? 涉及到CSS的繼承規(guī)則和層疊規(guī)則。

? 樣式計(jì)算階段的目的是為了計(jì)算出 DOM 節(jié)點(diǎn)中每個(gè)元素的具體樣式,在計(jì)算過(guò)程中需要遵守 CSS 的繼承和層疊兩個(gè)規(guī)則。這個(gè)階段最終輸出的內(nèi)容是每個(gè) DOM 節(jié)點(diǎn)的樣式,并被保存在 ComputedStyle 的結(jié)構(gòu)內(nèi)。

步驟三:
  • 根據(jù) DOM 樹(shù)和 CSSOM 規(guī)則樹(shù)構(gòu)建渲染樹(shù)。渲染樹(shù)的節(jié)點(diǎn)被稱為渲染對(duì)象,渲染對(duì)象是一個(gè)包含有顏色和大小等屬性的矩形,渲染對(duì)象和 DOM 元素相對(duì)應(yīng),但這種對(duì)應(yīng)關(guān)系不是一對(duì)一的,不可見(jiàn)的 DOM 元素不會(huì)被插入渲染樹(shù)。還有一些 DOM元素對(duì)應(yīng)幾個(gè)可見(jiàn)對(duì)象,它們一般是一些具有復(fù)雜結(jié)構(gòu)的元素,無(wú)法用一個(gè)矩形來(lái)描述。

步驟四:
  • 當(dāng)渲染對(duì)象被創(chuàng)建并添加到樹(shù)中,它們并沒(méi)有位置和大小,所以當(dāng)瀏覽器生成渲染樹(shù)以后,就會(huì)根據(jù)渲染樹(shù)來(lái)進(jìn)行布局(也可以叫做回流)。這一階段瀏覽器要做的事情是要弄清楚各個(gè)節(jié)點(diǎn)在頁(yè)面中的確切位置和大小。通常這一行為也被稱為“自動(dòng)重排”。

詳細(xì)過(guò)程:
因?yàn)轫?yè)面中有很多復(fù)雜的效果,如一些復(fù)雜的3D轉(zhuǎn)換,頁(yè)面滾動(dòng),或者使用z-index,為了更方便的實(shí)現(xiàn)這些效果,渲染引擎還需要為特定的節(jié)點(diǎn)生成專門的圖層,并生成一棵對(duì)應(yīng)的圖層樹(shù)(LayerTree)。這和PS的圖層類似,正是這些圖層疊加在一起才最終構(gòu)成了頁(yè)面圖像。

實(shí)際上,瀏覽器的頁(yè)面被分成了很多圖層,這些圖層疊加在一起后,最終合成了頁(yè)面。

布局樹(shù)和圖層樹(shù)的關(guān)系

通常情況下,并不是布局樹(shù)中的每一個(gè)節(jié)點(diǎn)都包含一個(gè)圖層,如果一個(gè)節(jié)點(diǎn)沒(méi)有對(duì)應(yīng)的圖層,那么這個(gè)節(jié)點(diǎn)就從屬于父節(jié)點(diǎn)的圖層。那么什么情況滿足,渲染引擎才會(huì)為特定的節(jié)點(diǎn)創(chuàng)建新的圖層呢?滿足一下兩個(gè)條件中的任意一個(gè),元素就可以被單獨(dú)提升為一個(gè)圖層。

1、擁有層疊上下文屬性的元素會(huì)被提升為單獨(dú)的一層。

頁(yè)面是一個(gè)二維平面,但層疊上下文能夠上HTML元素?fù)碛腥S概念,這些HTML元素按自身屬性的優(yōu)先級(jí)分布在垂直于這個(gè)二維平面的Z軸上,以下情況會(huì)作為單獨(dú)的圖層

1、position:fixed 2、css 3d 例如:transform:rotateX(30deg) 3、video 4、canvas 5、有css3動(dòng)畫的節(jié)點(diǎn)

2、需要剪裁的地方也會(huì)被創(chuàng)建為圖層

文字內(nèi)容溢出div的情況

把div的大小限定為200200像素,而div里面的文字內(nèi)容比較多,文字所顯示的區(qū)域肯定會(huì)超過(guò)200200的面積,這時(shí)候就產(chǎn)生了剪裁,渲染引擎會(huì)把裁剪文字內(nèi)容的一部分用于顯示在div區(qū)域,下面是運(yùn)行時(shí)的執(zhí)行結(jié)果:

出現(xiàn)這種裁剪情況時(shí),渲染引擎會(huì)為文字單獨(dú)為文字創(chuàng)建一層,如出現(xiàn)滾動(dòng)條,滾動(dòng)條也會(huì)被提升為單獨(dú)的層。

步驟五:
  • 布局階段結(jié)束后是繪制階段,遍歷渲染樹(shù)并調(diào)用渲染對(duì)象的 paint 方法將它們的內(nèi)容顯示在屏幕上,繪制使用 UI 基礎(chǔ)組件。

**注意:**這個(gè)過(guò)程是逐步完成的,為了更好的用戶體驗(yàn),渲染引擎將會(huì)盡可能早的將內(nèi)容呈現(xiàn)到屏幕上,并不會(huì)等到所有的html 都解析完成之后再去構(gòu)建和布局 render 樹(shù)。它是解析完一部分內(nèi)容就顯示一部分內(nèi)容,同時(shí),可能還在通過(guò)網(wǎng)絡(luò)下載其余內(nèi)容。

2.相關(guān)概念

“重排”,“重繪"和"合成”。

①重排(更新元素的幾何屬性)

如果你通過(guò)JS或css修改元素的幾何位置屬性,如width,height等,那么會(huì)觸發(fā)瀏覽器的重新布局,解析之后的一系列子階段,這個(gè)過(guò)程就叫重排重排需要更新完整的渲染流水線,所以開(kāi)銷也最大的。

②重繪(更細(xì)元素的繪制屬性)

修改元素的背景色,布局階段不會(huì)執(zhí)行,因?yàn)?strong>沒(méi)有引起幾何位置的變換,所以直接進(jìn)入繪制,然后執(zhí)行之后的一系列子階段,這個(gè)過(guò)程就叫重繪。相較重排操作,重繪省去了布局和分層階段,所以執(zhí)行效率會(huì)比重排效率高。

③直接合成階段

那如果你更改一個(gè)既不要布局也不要繪制的屬性,渲染引擎將跳過(guò)布局和繪制,只執(zhí)行后續(xù)的合成操作,我們把這個(gè)過(guò)程叫做合成。

使用CSS的transform來(lái)實(shí)現(xiàn)動(dòng)畫效果,可以避開(kāi)重排和重繪階段,直接在非主線程上執(zhí)行合成動(dòng)畫操作。這樣的效率最高,因?yàn)槭窃诜侵骶€程上合成的,并沒(méi)有占用主線程的資源。

三.瀏覽器渲染優(yōu)化

(1)針對(duì)JavaScript:

JavaScript既會(huì)阻塞HTML的解析,也會(huì)阻塞CSS的解析。因此我們可以對(duì)JavaScript的加載方式進(jìn)行改變,來(lái)進(jìn)行優(yōu)化:

(1)盡量將JavaScript文件放在body的最后

(2) body中間盡量不要寫<script>標(biāo)簽

(3)<script>標(biāo)簽的引入資源方式有三種,有一種就是我們常用的直接引入,還有兩種就是使用 async 屬性和 defer 屬性來(lái)異步引入,兩者都是去異步加載外部的JS文件,不會(huì)阻塞DOM的解析(盡量使用異步加載)。三者的區(qū)別如下:

  • script 立即停止頁(yè)面渲染去加載資源文件,當(dāng)資源加載完畢后立即執(zhí)行js代碼,js代碼執(zhí)行完畢后繼續(xù)渲染頁(yè)面;
  • async 是在下載完成之后,立即異步加載,加載好后立即執(zhí)行,多個(gè)帶async屬性的標(biāo)簽,不能保證加載的順序;
  • defer 是在下載完成之后,立即異步加載。加載好后,如果 DOM 樹(shù)還沒(méi)構(gòu)建好,則先等 DOM 樹(shù)解析好再執(zhí)行;如果DOM樹(shù)已經(jīng)準(zhǔn)備好,則立即執(zhí)行。多個(gè)帶defer屬性的標(biāo)簽,按照順序執(zhí)行。

(2)針對(duì)CSS:

css要放在頂部,它不會(huì)阻塞html的解析

使用CSS有三種方式:使用link、@import、內(nèi)聯(lián)樣式,其中l(wèi)ink和@import都是導(dǎo)入外部樣式。它們之間的區(qū)別:

  • link:瀏覽器會(huì)派發(fā)一個(gè)新的線程(HTTP線程)去加載資源文件,與此同時(shí)GUI渲染線程會(huì)繼續(xù)向下渲染代碼
  • @import:GUI渲染線程會(huì)暫時(shí)停止渲染,去服務(wù)器加載資源文件,資源文件沒(méi)有返回之前不會(huì)繼續(xù)渲染(阻礙瀏覽器渲染)
  • style:GUI直接渲染

外部樣式如果長(zhǎng)時(shí)間沒(méi)有加載完畢,瀏覽器為了用戶體驗(yàn),會(huì)使用瀏覽器會(huì)默認(rèn)樣式,確保首次渲染的速度。所以CSS一般寫在headr中,讓瀏覽器盡快發(fā)送請(qǐng)求去獲取css樣式。

所以,在開(kāi)發(fā)過(guò)程中,導(dǎo)入外部樣式使用link,而不用@import。如果css少,盡可能采用內(nèi)嵌樣式,直接寫在style標(biāo)簽中。

style樣式解析

瀏覽器一次是加載64kb,現(xiàn)在我們加載的頁(yè)面過(guò)大,所有會(huì)分段接收。

Tips: style中的樣式不解析完畢,頁(yè)面不會(huì)渲染。

1、由html解析器解析

2、不會(huì)阻塞瀏覽器渲染,但可能出現(xiàn)閃屏現(xiàn)象

3、不會(huì)阻塞DOM解析

通過(guò)style標(biāo)簽引入會(huì)一般解析,一邊渲染。

link引入

1、link進(jìn)來(lái)的樣式,由css解析器去解析,并且是同步解析的。

2、css解析器會(huì)阻塞頁(yè)面的渲染。(link引入的外部樣式會(huì)阻塞頁(yè)面渲染)

? (可以利用這種阻塞避免"閃屏現(xiàn)象")

3、推薦使用link引入樣式。

4.阻塞后面的js語(yǔ)句的執(zhí)行

(3)針對(duì)DOM樹(shù)、CSSOM樹(shù):

可以通過(guò)以下幾種方式來(lái)減少渲染的時(shí)間:

  • HTML文件的代碼層級(jí)盡量不要太深
  • 使用語(yǔ)義化的標(biāo)簽,來(lái)避免不標(biāo)準(zhǔn)語(yǔ)義化的特殊處理
  • 減少CSSD代碼的層級(jí),因?yàn)檫x擇器是從左向右進(jìn)行解析的

(4)減少回流與重繪:

  • 操作DOM時(shí),盡量在低層級(jí)的DOM節(jié)點(diǎn)進(jìn)行操作
  • 不要使用table布局, 一個(gè)小的改動(dòng)可能會(huì)使整個(gè)table進(jìn)行重新布局
  • 使用CSS的表達(dá)式
  • 不要頻繁操作元素的樣式,對(duì)于靜態(tài)頁(yè)面,可以修改類名,而不是樣式。
  • 使用absolute或者fixed,使元素脫離文檔流,這樣他們發(fā)生變化就不會(huì)影響其他元素
  • 避免頻繁操作DOM,可以創(chuàng)建一個(gè)文檔片段documentFragment,在它上面應(yīng)用所有DOM操作,最后再把它添加到文檔中
  • 將元素先設(shè)置display: none,操作結(jié)束后再把它顯示出來(lái)。因?yàn)樵赿isplay屬性為none的元素上進(jìn)行的DOM操作不會(huì)引發(fā)回流和重繪。
  • 將DOM的多個(gè)讀操作(或者寫操作)放在一起,而不是讀寫操作穿插著寫。這得益于瀏覽器的渲染隊(duì)列機(jī)制。

瀏覽器針對(duì)頁(yè)面的回流與重繪,進(jìn)行了自身的優(yōu)化——渲染隊(duì)列

瀏覽器會(huì)將所有的回流、重繪的操作放在一個(gè)隊(duì)列中,當(dāng)隊(duì)列中的操作到了一定的數(shù)量或者到了一定的時(shí)間間隔,瀏覽器就會(huì)對(duì)隊(duì)列進(jìn)行批處理。這樣就會(huì)讓多次的回流、重繪變成一次回流重繪。

將多個(gè)讀操作(或者寫操作)放在一起,就會(huì)等所有的讀操作進(jìn)入隊(duì)列之后執(zhí)行,這樣,原本應(yīng)該是觸發(fā)多次回流,變成了只觸發(fā)一次回流。

總結(jié)

以上是生活随笔為你收集整理的前端浏览器渲染原理及优化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。