<script>
標簽用于在HTML
中引入js
,本文主要討論三方面:
- script標簽在不同位置引入的區別(如在head引入和在body引入,在body開頭與最后引入)
- script標簽的三種引入方式(default,async,defer),
- script標簽模塊化(type='module')
加載與執行的區別
腳本的加載(Loading)與執行(Execution)是兩個獨立的概念,它們的行為和影響因素不同,理解這一點對我們后面的討論至關重要.
- 加載: 瀏覽器從服務器獲取腳本文件(如
script.js
)的過程,涉及網絡請求和資源下載。 - 執行: 瀏覽器解析并運行腳本中的 JavaScript 代碼。
引入位置區別
<head>
中引入或在<body>
最開始引入
瀏覽器會暫停 HTML 解析,立即加載并執行腳本,執行完成后才繼續解析 DOM。
若腳本體積大或網絡慢,會導致頁面渲染阻塞(白屏時間長)。
如果腳本嘗試操作 DOM(如 document.getElementById
),可能因為 DOM 還未解析而找不到元素,導致錯誤。
適用場景
- 需要盡早執行且不依賴 DOM 的腳本(如某些性能監控、日志上報代碼)。
- 一般不推薦,除非有特殊需求。
<body>
底部引入:
不阻塞 DOM 解析,瀏覽器會先解析完整的 HTML,最后再加載和執行腳本,不會影響頁面渲染速度。用戶能更快看到頁面內容(減少 FCP,First Contentful Paint)。
腳本執行時 DOM 已就緒,腳本運行時,整個 DOM 已經解析完成,可以安全操作 DOM 元素,無需等待 DOMContentLoaded
事件。
適用場景
- 推薦的經典做法,適用于大多數情況,特別是依賴 DOM 的腳本(如交互邏輯、初始化組件)。
- 如果腳本較大,仍可能影響
DOMContentLoaded
事件觸發時間。
三種引入
默認引入
遵循多個腳本按書寫順序依次加載并執行的原則。
defer
<script src="script.js" defer></script>
行為:
- 腳本異步加載(不阻塞 HTML 解析),但會延遲到 DOM 解析完成后、
DOMContentLoaded
事件前按順序執行。 - 適用于需要操作 DOM 或依賴其他腳本的場景。
特點:
- 保證腳本的執行順序(與書寫順序一致)。
- 天然支持“等 DOM 就緒”,類似
DOMContentLoaded
。
async
<script src="script.js" async></script>
行為:
- 腳本異步加載(不阻塞 HTML 解析),加載完成后立即執行(可能中斷 HTML 解析)。
- 適用于獨立腳本(如統計代碼、第三方 SDK)。
特點:
- 不保證執行順序(誰先加載完誰先執行)。
- 不適合操作 DOM 的腳本(可能 DOM 還未解析完)。
模塊化type="module"
<script type="module" src="module.js"></script>
場景:
行為:
- 避免全局變量污染,依賴關系清晰,適合大型項目。
- 默認具有
defer
行為(異步加載,DOM 解析后執行)。 - 若顯式添加
async
(如 <script type="module" async>
),則行為類似 async
。
特點:
- 支持 ES6 模塊語法(
import
/export
)。 - 自動啟用嚴格模式。
- 模塊腳本默認延遲執行,且按依賴關系順序執行。
?轉自https://juejin.cn/post/7491601352746680383
該文章在 2025/4/12 9:24:04 編輯過