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

通過Performance面板驗證瀏覽器資源加載與渲染機制

系統 瀏覽器
文檔對象模型(Document Object Model,簡稱 DOM),是 W3C 組織推薦的處理可擴展置標語言的標準編程接口。DOM 把整個頁面映射為一個多層的節點結構,HTML 或 XML 頁面中的每個組成部分都是某種類型的節點,這些節點又包含著不同類型的數據。

前言

一個網頁的核心由HTML、CSS和JavaScript組成,三者協同工作以呈現內容并實現交互。但瀏覽器如何解析這些資源?加載順序如何影響用戶體驗?讀完本本文你將徹底弄懂以下核心知識

  1. 為什么需要生成DOM樹?
  2. CSS是否會阻塞HTML解析?是否阻塞頁面渲染?
  3. JavaScript是否會阻塞HTML解析?
  4. JavaScript的異步加載機制如何影響解析過程?
  5. 如何通過performance面板驗證以上觀點

認識DOM

文檔對象模型(Document Object Model,簡稱 DOM),是 W3C 組織推薦的處理可擴展置標語言的標準編程接口。DOM 把整個頁面映射為一個多層的節點結構,HTML 或 XML 頁面中的每個組成部分都是某種類型的節點,這些節點又包含著不同類型的數據。

W3C DOM 由以下三部分組成:

  • 核心 DOM - 針對任何結構化文檔的標準模型
  • XML DOM - 針對 XML 文檔的標準模型
  • HTML DOM - 針對 HTML 文檔的標準模型

如果覺得這樣介紹不夠直觀,可以看下這張圖:

圖片圖片

各個dom節點組合起來就形成了一個樹狀結構,所以我們通常稱之為DOM樹

為什么需要DOM樹?

  • 結構化數據:將HTML標簽(如<div><p>)和文本內容轉化為節點對象,以樹形結構表示標簽的父子嵌套關系。
  • JavaScript動態操作的基礎:這一過程解決了原生HTML文本的局限性,允許JavaScript通過屬性與方法直接操作節點。
  • 渲染過程的核心輸入:DOM樹提供內容結構,CSSOM樹提供樣式規則,兩者結合生成渲染樹(Render Tree),決定頁面元素的可見性與布局。
  • 安全性:DOM解析階段會過濾惡意內容。

DOM 是瀏覽器對頁面的內部表示,也是 Web 開發人員可以通過 JavaScript 交互的數據結構和 API。

解析HTML

網絡線程獲取HTML文件后,瀏覽器才會開始進行解析處理生成DOM樹。

圖片圖片

在這個過程中每個HTML標簽都會被瀏覽器解析成文檔對象,并且所有的文檔對象最終都會被掛在document

比如:

圖片圖片

并且為了提高解析效率,在解析之前,瀏覽器會啟動一個預解析的線程,提前去下載文檔中的外部CSS文件和外部JS文件。

解析CSS

在構建DOM的過程中,如果遇到link標簽,當把它插入到DOM樹上后,此時如果外部的CSS文件還沒有下載完,主線程也不會停下來等待,因為下載和解析CSS的工作是在預解析線程中進行的,所以CSS并不會阻塞html的解析。

解析html的目的是為了生成DOM樹,而解析CSS的目的同樣是為了生成CSSOM樹,兩者都是為了轉換成瀏覽器能夠理解的結構,也可以方便javascript的訪問。

我們可以通過document.styleSheets來查看它的結構:

圖片圖片

CSSOM結構主要是為了給JavaScript提供操作樣式表的能力,以及提供基礎的樣式信息

大體上來說,CSSOM是一個建立在web頁面上的 CSS 樣式的映射,它和DOM類似,但是只針對CSS而不是HTML,瀏覽器會將DOM和CSSOM結合生成渲染樹。

CSS是否會阻塞渲染?

雖然CSS并不會阻塞html的解析,但由于渲染樹的生成需要CSSOM的參與,所以CSS是會阻塞頁面渲染的

真的原因是,如果瀏覽器在CSS檢查之前展示了頁面,那么每個頁面都是沒有樣式的,等一會之后又突然有了樣式,整個頁面的體驗就會很差。由于CSSOM被用作創建渲染樹,那么如果不能高效的利用CSS會導致白屏時間的增加

解析javascript

在構建DOM的過程中,如果遇到script,在默認情況下主線程會停止對html的解析,轉而等待 JS 文件下載好,并將全局代碼解析執行完成后,才會繼續解析html。這是因為 JS 代碼的執行過程可能會修改當前的 DOM 樹,所以 DOM 樹的生成必須暫停。這就是 JS 會阻塞 HTML 解析的根本原因。

在html5中對script新增了兩個屬性可用于異步加載腳本,設置不同的屬性對解析HTML文檔也有很大的影響。

異步加載

圖片

這里我們要討論的不僅僅是asyncdefer,還有type=module

默認情況
  • 在默認情況下,script 標簽在請求和執行的時候都會阻塞文檔解析
defer

延遲腳本執行:帶有defer屬性的腳本,加載不會阻塞頁面的解析和渲染過程,瀏覽器可以繼續解析頁面的其余部分,當整個文檔完成解析后,在觸發DOMContentLoaded事件之前執行這些腳本。

順序執行:帶有defer屬性的腳本,盡管是異步加載的,但是它們之間會保持順序執行。

async

非阻塞加載:帶有async屬性的腳本加載是異步的,不會阻塞HTML文檔的解析,瀏覽器可以繼續向下解析和渲染。不過,當腳本加載完成后,會立即執行腳本內的代碼,此時如果HTML還沒有解析完成,則會暫停對html的解析,從而阻塞頁面渲染。但如果當腳本加載完準備執行之前,html已經解析完成,此時也不會阻塞頁面渲染。

執行不可控:帶有async屬性的腳本,執行是不可控的,因為無法確定腳本的下載速度與腳本內容的執行速度,如果存在多個script async時,他們之間的執行的順序也是不可控的,完全取決于各自的下載速度,誰先下載完成就先執行誰。

module

非阻塞加載:帶有type="module"的腳本加載是異步的,這類標簽視為ES6模塊來處理,而ES6模塊是設計為異步加載的,當瀏覽器遇到此類標簽時,會開始異步下載改模塊及其依賴項,不會暫停頁面的解析和渲染工作,當HTML文檔被解析完成后,會在觸發DOMContentLoaded事件之前執行這些腳本。所以它的表現有點類似defer

模塊化支持:帶有type="module"的腳本會自動分割成不同的模塊,并且相互之間作用域是隔離的,瀏覽器會自動加載這些模塊,無需手動管理依賴關系。

支持靜態導入和動態導入:可以使用import語句靜態地導入其它模塊,這些導入的模塊加載時自動解析和執行。還可以使用import()函數動態地導入模塊,根據需要在運行時加載模塊,進一步控制模塊的加載和執行時機。

module && async

表現類似async

通過performance驗證

實驗代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./a.css" />
    <script>
        console.log('【readystatechange】', document.readyState)
        document.addEventListener('readystatechange', (e) => {
            console.log('【readystatechange】', document.readyState)
        })
        window.addEventListener('load', (e) => {
            console.log('【load】')
        })

        document.addEventListener('DOMContentLoaded', (e) => {
            console.log('【DOMContentLoaded】')
        })        
    </script>
    <script defer src="./a.js"></script>
    <script async src="./b.js"></script>
    <script src="./c.js"></script>
</head>
<body>
    <div class="container"></div>
</body>
</html>

網絡

頁面中分別引入了一個css資源,三個JS資源以及一個內聯腳本,我們可以看下各資源的加載情況

圖片圖片

首先肯定是先加載html文件,而html中的cssjs資源會以他們在文檔中的順序依次進行請求加載,由于內聯腳本無需再發起請求,所以在網絡模塊中也不會有它的存在。

注意看紅線位置,這是html開始解析的時間點,從network模塊上看,內部的css與js資源竟然在這之前就發起了請求,這也就驗證了為了加速,瀏覽器的預加載掃描器會同時運行,如果在 html 中存在  <link><script>img 等標簽,預加載掃描器會把這些請求傳遞給瀏覽器進程中的網絡線程進行相關資源的下載。

從圖中我們可以看到,a.cssc.js文件右上角都出現了紅色標注,這是代表這兩個文件都會阻塞頁面的渲染

圖片圖片

為了更清晰的了解各模塊的加載解析與渲染之間的關系,我們可以查看下方的主線程模塊

主線程

圖片圖片

可以看到html的解析、css的解析、腳本的執行、頁面渲染等都發生在主線程

parse html

在瀏覽器渲染引擎內部,有一個叫HTML 解析器(HTMLParser)的模塊,它負責將HTML字節流轉換為DOM結構。HTML Standard規范定義了瀏覽器渲染HTML為DOM的方法。

??需要注意的是HTML解析器并不是等整個文檔加載完成之后再解析的,而是網絡進程加載了多少數據,HTML解析器就解析多少數據。

圖片圖片

注意看,第一次解析html的范圍是0-24,解析過程遇到了css資源,等css資源下載完成后會開始解析css(這個過程不會阻塞html的解析)

parse stylesheet

圖片圖片

Evaluate script

再往后就遇到了內聯腳本,這個時候會停下來解析執行JS(這才是導致html解析暫停的根本原因)

圖片圖片

等腳本執行完后會繼續解析html

圖片圖片

注意range,跟上一次parse html剛好接上了

接著往后會依次遇到a、b、c三個腳本,由于c沒有添加任何異步屬性,所以c會率先開始執行(此時會阻塞html的解析)

圖片圖片

執行完成后會繼續解析html

圖片圖片

等解析完成后會開始執行標記了defera.js(a.js在這之前就已加載完成)

圖片圖片

最后標記了asyncb.js加載完成,會立即執行

圖片圖片

責任編輯:武曉燕 來源: 前端南玖
相關推薦

2013-11-20 10:47:57

瀏覽器渲染html

2020-11-06 15:20:45

瀏覽器前端架構

2017-10-09 13:39:26

瀏覽器渲染服務器

2019-04-08 10:27:00

渲染瀏覽器DOM

2013-11-18 14:42:53

瀏覽器渲染

2017-11-21 14:56:59

2012-06-01 10:28:54

Web

2012-06-06 15:57:29

Web

2013-06-14 13:56:29

瀏覽器渲染原理

2013-05-23 16:01:56

瀏覽器

2017-04-26 14:15:35

瀏覽器緩存機制

2018-01-19 14:39:53

瀏覽器頁面優化

2013-11-20 13:47:43

瀏覽器渲染引擎

2022-08-30 09:01:11

瀏覽器渲染前端

2017-03-08 08:31:48

瀏覽器渲染路徑

2017-08-03 12:50:49

Web圖片資源瀏覽器

2021-01-07 07:52:04

瀏覽器網頁資源加載

2015-02-28 09:39:24

Windows 10Spartan

2017-03-12 10:15:18

瀏覽器DOM樹CSSOM樹

2021-12-17 00:02:28

Webpack資源加載
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 看片国产 | 国产良家自拍 | 中文字幕欧美在线观看 | 91在线区| 免费观看一区二区三区毛片 | 国产精品一区二区av | 亚洲国产中文在线 | 国外成人免费视频 | 精品国产99| 欧美黄色绿像 | 亚洲女人天堂成人av在线 | 国产精品亚洲一区二区三区在线 | 日韩中文字幕 | 日本精品一区二区三区在线观看视频 | 精品动漫一区 | 国产精品久久久久无码av | 91欧美 | 久久成人免费视频 | 国产精品不卡一区 | 国产伦精品一区二区三区照片91 | 日韩欧美一区二区三区免费观看 | 国产精品成人av | 91国产视频在线 | 亚洲成a人片| 国产精品美女久久久久aⅴ国产馆 | 国产精品高潮呻吟久久av野狼 | 999久久久久久久久 国产欧美在线观看 | 久久久www| 久久精品女人天堂av | 国产91丝袜在线熟 | 91.色 | 99九九视频 | 99re国产| 免费1区2区3区 | 国产yw851.c免费观看网站 | 美女中文字幕视频 | 一区日韩| 99亚洲精品 | 亚洲视频在线看 | 亚洲视频中文字幕 | 亚洲精彩视频在线观看 |