Web 瀏覽器是一種軟件,它從遠程服務器(或者本地磁盤)加載文件並將其顯示——使用戶能夠與之交互。瀏覽器中有一個軟件叫瀏覽器引擎。在不一樣的瀏覽器中,瀏覽器的某個部分會根據它接收到的文件肯定顯示什麼,這就是所謂的瀏覽器引擎。瀏覽器引擎是每一種主流瀏覽器的核心軟件組件,不一樣的瀏覽器開發商用不一樣的名字來稱呼他們的引擎。javascript
但標記還不是最終的結果。標記化完成後,接下來,標記將被轉換爲節點。你能夠將節點看做是具備特定屬性的不一樣對象。實際上,更好的解釋是,將節點看做是文檔對象樹中的獨立實體。但節點仍然不是最終結果。 如今,讓咱們看一下最後一點。在建立好以後,這些節點將被連接到稱爲DOM 的樹數據結構中。DOM 創建起了父子關係、相鄰兄弟關係等。在這個 DOM 對象中,每一個節點之間都創建了關係。如今,這是咱們可使用的東西了。css
這個是咱們很常見的寫法html
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="test.css" /> </head> <body> </body> </html> 複製代碼
當瀏覽器接收到原始數據字節並啓動 DOM 構建過程時,它還會發出請求來獲取連接的 test.css 樣式表。當瀏覽器開始解析 HTML 時,在找到 css 文件的連接標籤的同時,它會發出請求來獲取它。可能你已經猜到,瀏覽器仍是接收 CSS 數據的原始字節,從互聯網或是本地磁盤。java
當瀏覽器接收到 CSS 的原始字節時,會啓動一個和處理 HTML 原始字節相似的過程。就是說,原始數據字節被轉換成字符,而後標記,而後造成節點,最後造成樹結構。 什麼是樹結構?大多數人都知道 DOM 這個詞。一樣,也有一種 CSS 樹結構,,瀏覽器不能使用 HTML 或 CSS 的原始字節。必須將其轉換成它能識別的形式,也就是這些樹形結構。瀏覽器
渲染樹包含頁面上全部關於可見 DOM 內容的信息以及不一樣節點所需的全部 CSSOM 信息。注意,若是一個元素被 CSS 隱藏,例如使用 display; none,那麼節點就不會包含在渲染樹中。隱藏元素會出如今 DOM 中,但不會出如今渲染樹中。這是由於渲染樹結合了來自 DOM 和 CSSOM 的信息,因此它知道不能把隱藏元素包含在樹中。服務器
咱們已經獲得了在屏幕上顯示元素所需的全部信息。咱們只要把它展現給用戶。這就是這個階段的所有工做。有了元素內容(DOM)、樣式(CSSOM)和計算得出的元素的精確佈局信息,瀏覽器如今就能夠將節點逐個「繪製」到屏幕上了。元素能夠呈如今屏幕上了!markdown
通俗的解釋爲有東西阻止了屏幕上節點的實際繪製,在成功繪製以前,必須構造 DOM 和 CSSOM,所以,HTML 和 CSS 都是渲染阻塞資源。網絡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>testRander</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<p>瀏覽器頁面渲染機制</p>
<img src="http://spage.haimati.cn/activityImage/newplan.jpg">
</body>
</html>
複製代碼
這是一個很是常見的文檔。樣式表 style.css簡單定義樣式:數據結構
* { font-size: 20px; } body { background-color: antiquewhite; } 複製代碼
一段簡單的文本和圖像呈如今屏幕上。async
根據前面的解釋,瀏覽器從磁盤(或網絡)讀取 HTML 文件的原始字節並將其轉換爲字符。字符被進一步解析爲標記。當解析器遇到< link rel="stylesheet" href="style.css">時,就會請求獲取 CSS 文件 style.css。DOM 構造繼續進行,當 CSS 文件返回一些內容後,CSSOM 構造就開始了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>testRander</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<p id="title">瀏覽器頁面渲染機制</p>
<img src="http://spage.haimati.cn/activityImage/newplan.jpg">
<script>
let title = document.getElementById("title");
console.log("title is: ", title);
</script>
</body>
</html>
複製代碼
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>testRander</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script>
let title = document.getElementById("title");
console.log("title is: ", title);
</script>
<p id="title">瀏覽器頁面渲染機制</p>
<img src="http://spage.haimati.cn/activityImage/newplan.jpg">
</body>
</html>
複製代碼
當腳本試圖訪問一個 id 爲 header 的 DOM 節點時,因爲 DOM 尚未完成對文檔的解析,因此它還不存在。這把咱們帶到了另外一個重要的問題。腳本的位置很重要。
在默認狀況下,每一個腳本都是一個解析器阻斷器!DOM 的構建老是會被打斷。不過,有一種方法能夠改變這種默認行爲。若是將 async 關鍵字添加到腳本標籤中,那麼 DOM 構造就不會中止。DOM 構造將繼續,腳本將在下載完成並準備就緒後執行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>testRander</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="test.js" async></script>
<p id="title">瀏覽器頁面渲染機制</p>
<img src="http://spage.haimati.cn/activityImage/newplan.jpg">
</body>
</html>
複製代碼
把js放入test.js中進行引入
let title = document.getElementById("title"); console.log("title is: ", title); 複製代碼
這樣DOM的構建就不會中止,腳本在構造完成後執行。