css的載入會阻塞js執行嗎?為什麼?

王铁柱6發表於2024-12-04

CSS 的載入會阻塞 DOM樹的構建,從而間接阻塞 依賴 DOM 結構的 JavaScript 程式碼的執行,但不會阻塞其他 JavaScript 程式碼的下載和解析。

具體來說:

  1. 瀏覽器渲染過程: 瀏覽器渲染頁面需要構建 DOM 樹(描述 HTML 結構)和 CSSOM 樹(描述 CSS 樣式),然後合併成渲染樹,最終繪製到螢幕上。

  2. CSS 的阻塞特性: 為了避免渲染未樣式化的內容導致頁面閃爍或重繪,瀏覽器會優先下載並解析 CSS,構建 CSSOM 樹。在此期間,DOM 樹的構建會被暫停。

  3. JavaScript 的依賴性: 如果 JavaScript 程式碼依賴於 DOM 結構(例如,透過 document.getElementById 獲取元素),那麼它必須等待 DOM 樹構建完成才能執行。因此,如果 CSS 載入緩慢,就會阻塞依賴 DOM 的 JavaScript 程式碼的執行。

  4. 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 樹構建完成。

希望以上解釋能夠解答你的疑問。

相關文章