目錄
- JavaScript 標簽加載
- script 標簽的 async 和 defer 屬性,分別代表什么,有什么區別
- 1. 普通 script 標簽
- 2. async 屬性
- 3. defer 屬性
- 4. type="module"
- 5. 各種加載方式的對比
- 6. 使用建議
JavaScript 標簽加載
script 標簽的 async 和 defer 屬性,分別代表什么,有什么區別
標準答案:
1. 普通 script 標簽
<script src="script.js"></script>
- 加載和執行都會阻塞 HTML 解析
- 按照在文檔中的順序執行
- 在全局作用域中執行
- 可以訪問全局變量和函數
- 不支持跨域加載(除非設置 CORS)
2. async 屬性
<scriptasyncsrc="script.js"
></script>
- 異步加載腳本,不阻塞 HTML 解析
- 加載完成后立即執行,可能會中斷 HTML 解析
- 適用于獨立腳本,如第三方統計、廣告等
- 執行順序不保證,誰先加載完誰先執行
- 在全局作用域中執行
- 可以訪問全局變量和函數
- 不支持跨域加載(除非設置 CORS)
3. defer 屬性
<scriptdefersrc="script.js"
></script>
- 異步加載腳本,不阻塞 HTML 解析
- 等待 HTML 解析完成后,DOMContentLoaded 事件前執行
- 多個 defer 腳本按照在文檔中的順序執行
- 適用于需要操作 DOM 或依賴頁面結構的腳本
- 在全局作用域中執行
- 可以訪問全局變量和函數
- 不支持跨域加載(除非設置 CORS)
4. type=“module”
<scripttype="module"src="script.js"
></script>
- 異步加載腳本,不阻塞 HTML 解析
- 默認具有 defer 屬性,等待 HTML 解析完成后執行
- 支持 ES6 模塊系統,可以使用 import/export
- 嚴格模式(‘use strict’)下執行
- 具有自己的作用域,不會污染全局作用域
- 支持跨域加載(需要設置 CORS)
- 只能通過 HTTP(S) 協議加載,不能通過 file:// 協議加載
- 模塊只會被加載一次,即使多次引用也只會執行一次
- 模塊加載順序按照 import 語句的順序執行
5. 各種加載方式的對比
特性 | 普通 script | async | defer | type=“module” |
---|---|---|---|---|
加載方式 | 同步 | 異步 | 異步 | 異步 |
執行時機 | 立即執行 | 加載完立即執行 | HTML 解析完成后執行 | HTML 解析完成后執行 |
執行順序 | 按文檔順序 | 不保證順序 | 按文檔順序 | 按 import 順序 |
作用域 | 全局 | 全局 | 全局 | 模塊作用域 |
嚴格模式 | 可選 | 可選 | 可選 | 強制 |
跨域支持 | 需要 CORS | 需要 CORS | 需要 CORS | 需要 CORS |
協議要求 | 無 | 無 | 無 | 必須 HTTP(S) |
模塊支持 | 不支持 | 不支持 | 不支持 | 支持 |
重復加載 | 會重復執行 | 會重復執行 | 會重復執行 | 只執行一次 |
6. 使用建議
-
普通 script:
- 適用于簡單的腳本
- 需要立即執行的腳本
- 對加載順序有嚴格要求的腳本
-
async:
- 適用于獨立的第三方腳本
- 不依賴 DOM 的腳本
- 統計、分析等工具腳本
-
defer:
- 適用于需要操作 DOM 的腳本
- 依賴頁面結構的腳本
- 需要按順序執行的腳本
-
type=“module”:
- 適用于現代 JavaScript 應用
- 需要模塊化的代碼
- 需要嚴格作用域的代碼
- 需要代碼復用的場景