JavaScript - script 標籤屬性(async & defer)
當 JavaScript 的檔案越多,網頁載入的時間越久,為了縮減使用者等待的時間,可以使用<script>
標籤上的 async
或 defer
屬性,讓 script 檔案異步加載,加速網頁載入時間,提升使用者體驗。
Regular
沒有加上其他屬性的 <script>
標籤。
1 | <script src="demo.js"></script> |
根據在 HTML 中所處位置的不同,對程式會有不同的影響。
<script>
處於 <head>
中 :
用戶載入頁面,瀏覽器開始解析 HTML,構建 DOM tree,當解析到 <script>
後,停止解析 HTML,而開始載入 <script>
中的檔案, 並執行 JavaScript 程式,最後才繼續解析剩下的 HTML。
這代表 JavaScript 會在 DOM 建構完成之前執行,需要操作 DOM 的程式就會因此無法執行。
<script>
處於 <body>
的最後一行 :
瀏覽器解析 HTML 是一行一行向下執行,所以將 <script>
放到 <body>
的最後一行就可以保證瀏覽器已將 HTML 解析完畢,DOM tree 建構完成,如此執行 JavaScript 程式就不會出現問題。
async
1 | <script async src="demo.js"></script> |
async
屬性表示 script
中的檔案為異步加載,在瀏覽器解析 HTML 時,<script>
中的檔案正異步加載,當載入完成後停止解析 HTML,立即執行 JavaScrip 程式,結束後才繼續解析 HTML。
通常 DOMContentLoaded
事件會在所有 <script>
檔案載入後才觸發,但是當使用 async
屬性時,只要 HTML 解析完畢,該事件就會直接觸發。
使用時機 :
不操作 DOM,且不在意 <script>
檔案執行順序時可以使用。適用於獨立的第三方 script,如 Google Analytics。
defer
1 | <script defer src="demo.js"></script> |
defer
屬性表示將 JavaScript 程式推遲到 HTML 解析完畢後才執行。在瀏覽器解析 HTML 時,<script>
中的檔案正異步加載,當 HTML 解析完成後,才執行 JavaScrip 程式。
三者比較
不同屬性的執行流程圖 :