問題回顧(HTML/CSS)

Q

要在 HTML 檔案中使用<script> 標籤載入 JavaScript 檔案時,一個常見的作法是「把 <script> 標籤放在 <body> 的最底部 (也就是 </body> 前)」。請問:

  1. 這樣做的話,在瀏覽器渲染流程中,會在什麼時機點載入到 JavaScript 程式碼?為什麼需要這樣做?
  2. 如果我們想要「在 DOM 生成的同時,一併載入 JavaScript」,針對 script 標籤還有什麼其他的處理作法?

A

  1. 瀏覽器渲染流程中,會在什麼時機點載入到 JavaScript 程式碼?
    JavaScript 無法直接操作 HTML 。
    瀏覽器渲染(render)畫面,會由上到下解析 HTML 轉成 JavaScript 可以操作的物件模型 DOM
    JavaScript 透過 DOM API 的方式完整操作 HTML 的內容
    <script> 放置在 <body> 最底部的主要原因是:確保 HTML DOM 已經完全被解析。
    若沒有放是在<body>最底部,當瀏覽器碰到 <script> 會暫停解析 DOM ,先下載與執行 <script> ,造成:
    等待下載 <script> 的時間,網頁繪製暫停,會造成頁面空白,影響使用者體驗
    DOM 沒有解析完成,卻已經執行 script 中需要操作的 HTML 元素

  2. 「在 DOM 生成的同時,一併載入 JavaScript」,針對 script 標籤還有什麼其他的處理作法?
    defer
    async
    與傳統 <script> 放置在 </body> 不同的的是:
    兩種做法都是在 HTML 解析成 DOM 的過程中進行下載,不會造成網頁繪製過程暫停
    defer 與 async 不同的是在多個 script 檔案的順序:

不論下載進度如何,defer 可以確保執行順序,例如

1
<script src="app1.js" defer></script>
1
<script src="app2.js" defer></script>

執行順序由上至下,app1.js > app2.js
async 則是依照下載速度,先下載完的 script 先執行。
使用情境上:defer 適用於 script 兼有相依性,async 則相反。