CSS 的載入會阻塞 DOM樹的構建,從而間接阻塞 依賴 DOM 結構的 JavaScript 程式碼的執行,但不會阻塞其他 JavaScript 程式碼的下載和解析。
具體來說:
-
瀏覽器渲染過程: 瀏覽器渲染頁面需要構建 DOM 樹(描述 HTML 結構)和 CSSOM 樹(描述 CSS 樣式),然後合併成渲染樹,最終繪製到螢幕上。
-
CSS 的阻塞特性: 為了避免渲染未樣式化的內容導致頁面閃爍或重繪,瀏覽器會優先下載並解析 CSS,構建 CSSOM 樹。在此期間,DOM 樹的構建會被暫停。
-
JavaScript 的依賴性: 如果 JavaScript 程式碼依賴於 DOM 結構(例如,透過
document.getElementById
獲取元素),那麼它必須等待 DOM 樹構建完成才能執行。因此,如果 CSS 載入緩慢,就會阻塞依賴 DOM 的 JavaScript 程式碼的執行。 -
JavaScript 的下載和解析: 雖然 CSS 會阻塞 DOM 樹的構建,但它不會阻塞瀏覽器下載和解析 JavaScript 檔案。瀏覽器會並行下載和解析 CSS 和 JavaScript,只是 JavaScript 的執行可能會被延遲。
總結:
- CSS 載入會阻塞 DOM 樹構建。
- 阻塞 DOM 樹構建會間接阻塞依賴 DOM 的 JavaScript 程式碼執行。
- CSS 載入不會阻塞 JavaScript 檔案的下載和解析。
示例:
<head>
<link rel="stylesheet" href="style.css">
<script>
console.log(document.getElementById('myDiv')); // 這行程式碼會被阻塞,直到 style.css 載入完成
</script>
<script>
console.log('This will print first!'); // 這行程式碼不會被阻塞
</script>
</head>
<body>
<div id="myDiv">Hello</div>
</body>
在這個例子中,第一個 console.log
會被阻塞,因為它依賴於 myDiv
元素,而 myDiv
元素的解析依賴於 DOM 樹的構建,而 DOM 樹的構建會被 style.css
的載入阻塞。第二個 console.log
不會被阻塞,因為它不依賴於 DOM 結構。
因此,為了最佳化頁面效能,建議:
- 將 CSS 放在
<head>
中: 使 CSS 儘早載入,減少阻塞時間。 - 使用媒體查詢最佳化 CSS 載入: 例如
<link rel="stylesheet" href="print.css" media="print">
,只在需要時載入特定 CSS。 - 避免在 CSS 中使用
@import
:@import
會導致額外的網路請求,增加載入時間。 - 儘量減少 JavaScript 對 DOM 的依賴: 或者將依賴 DOM 的 JavaScript 程式碼放在
<body>
底部,或者使用 DOMContentLoaded 事件監聽 DOM 樹構建完成。
希望以上解釋能夠解答你的疑問。