Q
要在 HTML 檔案中使用<script>
標籤載入 JavaScript 檔案時,一個常見的作法是「把 <script>
標籤放在 <body>
的最底部 (也就是 </body>
前)」。請問:
- 這樣做的話,在瀏覽器渲染流程中,會在什麼時機點載入到 JavaScript 程式碼?為什麼需要這樣做?
- 如果我們想要「在 DOM 生成的同時,一併載入 JavaScript」,針對 script 標籤還有什麼其他的處理作法?
A
瀏覽器渲染流程中,會在什麼時機點載入到 JavaScript 程式碼?
JavaScript 無法直接操作 HTML 。
瀏覽器渲染(render)畫面,會由上到下解析 HTML 轉成 JavaScript 可以操作的物件模型 DOM
JavaScript 透過 DOM API 的方式完整操作 HTML 的內容
將<script>
放置在<body>
最底部的主要原因是:確保 HTML DOM 已經完全被解析。
若沒有放是在<body>
最底部,當瀏覽器碰到<script>
會暫停解析 DOM ,先下載與執行<script>
,造成:
等待下載<script>
的時間,網頁繪製暫停,會造成頁面空白,影響使用者體驗
DOM 沒有解析完成,卻已經執行 script 中需要操作的 HTML 元素「在 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 則相反。