JavaScript 腳本異步加載的幾種實(shí)現(xiàn)方法
JavaScript 腳本異步加載主要通過(guò)以下方式實(shí)現(xiàn),它們?cè)?strong>加載時(shí)機(jī)、執(zhí)行順序和阻塞行為上有明顯區(qū)別:
一、實(shí)現(xiàn)方式及區(qū)別
1.async屬性
<script src="script.js" async></script>
- 特點(diǎn):
- 異步下載腳本,下載完成后立即執(zhí)行(可能中斷 HTML 解析)。
- 多個(gè)
async腳本的執(zhí)行順序不確定(先下載完先執(zhí)行)。
- 適用場(chǎng)景:獨(dú)立腳本(如統(tǒng)計(jì)代碼、廣告加載),無(wú) DOM 依賴或無(wú)需嚴(yán)格順序。
2.defer屬性
<script src="script.js" defer></script>
- 特點(diǎn):
- 異步下載腳本,但延遲到 HTML 解析完成后、
DOMContentLoaded事件前按順序執(zhí)行。 - 多個(gè)
defer腳本嚴(yán)格按聲明順序執(zhí)行。
- 異步下載腳本,但延遲到 HTML 解析完成后、
- 適用場(chǎng)景:依賴 DOM 或需要按序執(zhí)行的腳本(如庫(kù)文件+業(yè)務(wù)代碼)。
3.動(dòng)態(tài)創(chuàng)建script標(biāo)簽
const script = document.createElement('script');
script.src = 'script.js';
document.head.appendChild(script); // 添加到文檔后開(kāi)始加載
- 特點(diǎn):
- 默認(rèn)行為類似
async(下載完成后立即執(zhí)行,順序不確定)。 - 可通過(guò)
script.async = false改為按順序執(zhí)行(模擬defer)。
- 默認(rèn)行為類似
- 控制權(quán):可自由控制加載時(shí)機(jī)(例如用戶交互后加載)。
4.ES6 模塊(type="module")
<script type="module" src="module.js"></script>
- 特點(diǎn):
- 默認(rèn)具有
defer特性(延遲到 HTML 解析后執(zhí)行,且按順序)。 - 添加
async屬性后行為類似常規(guī)async(下載完立即執(zhí)行,順序不確定)。
- 默認(rèn)具有
- 注意:支持模塊化語(yǔ)法(
import/export),兼容現(xiàn)代瀏覽器。
二、關(guān)鍵區(qū)別對(duì)比
| 方式 | 是否阻塞 HTML 解析 | 執(zhí)行順序保證 | 觸發(fā)時(shí)機(jī) |
|---|---|---|---|
| async | ?(異步下載) | ? | 下載完成立即執(zhí)行 |
| defer | ?(異步下載) | ? | HTML 解析后,DOMContentLoaded 前 |
| 動(dòng)態(tài)腳本(默認(rèn)) | ? | ? | 下載完成立即執(zhí)行 |
| 動(dòng)態(tài)腳本+async=false | ? | ? | 按添加順序執(zhí)行 |
| ES6 模塊(默認(rèn)) | ? | ? | 同 defer |
三、使用建議
- 優(yōu)先使用 defer:
- 將腳本放在 <head> 中,避免渲染阻塞,同時(shí)保證執(zhí)行順序(如依賴 jQuery 的插件)。
- 獨(dú)立腳本用 async:
- 用于無(wú)依賴的腳本(如 Google Analytics)。
- 動(dòng)態(tài)加載非關(guān)鍵腳本:
- 用戶交互后或延遲加載非首屏必需的腳本(如評(píng)論區(qū)、懶加載庫(kù))。
- 現(xiàn)代項(xiàng)目使用 ES6 模塊:
- 兼顧模塊化和加載性能(需配合打包工具如 Webpack 優(yōu)化)。
四、注意事項(xiàng)
- 避免在異步腳本中使用
document.write(可能導(dǎo)致頁(yè)面崩潰)。 - 可通過(guò)
onload/onerror事件監(jiān)聽(tīng)加載狀態(tài):script.onload = () => console.log('加載成功'); script.onerror = () => console.log('加載失敗'); - 兼容性:
defer/async兼容 IE10+,動(dòng)態(tài)加載無(wú)兼容問(wèn)題。
總結(jié)
異步加載的核心目標(biāo)是減少頁(yè)面渲染阻塞,根據(jù)腳本是否依賴 DOM 或其他腳本選擇合適方案:
- 順序重要 → defer
- 順序無(wú)關(guān) → async
- 精細(xì)控制 → 動(dòng)態(tài)加載
- 模塊化項(xiàng)目 → ES6 模塊
到此這篇關(guān)于JavaScript 腳本異步加載的幾種實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)JavaScript 腳本異步加載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript 用Node.js寫Shell腳本[譯]
你懂JavaScript嗎?你需要寫一個(gè)Shell腳本嗎?那么你應(yīng)該試一下Node.js,它很容易安裝,而且很適合通過(guò)寫Shell腳本來(lái)學(xué)習(xí)它2012-09-09
JavaScript數(shù)組reduce()方法的語(yǔ)法與實(shí)例解析
js函數(shù)中有三個(gè)在特定場(chǎng)合很好用的函數(shù):reduce(),map(),filter(),這篇文章主要給大家介紹了關(guān)于JavaScript數(shù)組reduce()方法的相關(guān)資料,需要的朋友可以參考下2021-07-07
詳解基于DllPlugin和DllReferencePlugin的webpack構(gòu)建優(yōu)化
這篇文章主要介紹了詳解基于DllPlugin和DllReferencePlugin的webpack構(gòu)建優(yōu)化,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
微信小程序如何實(shí)現(xiàn)精確的日期時(shí)間選擇器
這篇文章主要介紹了微信小程序如何實(shí)現(xiàn)精確的日期時(shí)間選擇器,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
分享javascript計(jì)算時(shí)間差的示例代碼
這篇文章主要為大家介紹了javascript計(jì)算時(shí)間差的示例代碼,,一般來(lái)說(shuō)都是計(jì)算當(dāng)前時(shí)間和一個(gè)指定時(shí)間點(diǎn)之間的差距,感興趣的小伙伴們可以參考一下2016-01-01
理解JavaScript設(shè)計(jì)模式中的單例模式
這篇文章主要介紹了理解JavaScript設(shè)計(jì)模式中的單例模式,單例模式即Singleton?Pattern是最簡(jiǎn)單的設(shè)計(jì)模式之一,下文更多相關(guān)介紹感興趣的小伙伴可以參考一下2022-04-04

