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