国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

關(guān)于Javascript中defer和async的區(qū)別總結(jié)

2019-11-20 08:56:22
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

首先來(lái)看看這三句話:

<script src="script.js"></script>

沒(méi)有 defer 或 async,瀏覽器會(huì)立即加載并執(zhí)行指定的腳本,“立即”指的是在渲染該 script 標(biāo)簽之下的文檔元素之前,也就是說(shuō)不等待后續(xù)載入的文檔元素,讀到就加載并執(zhí)行。

<script async src="script.js"></script>

有 async,加載和渲染后續(xù)文檔元素的過(guò)程將和 script.js 的加載與執(zhí)行并行進(jìn)行(異步)。

<script defer src="myscript.js"></script>

有 defer,加載后續(xù)文檔元素的過(guò)程將和 script.js 的加載并行進(jìn)行(異步),但是 script.js 的執(zhí)行要在所有元素解析完成之后,DOMContentLoaded 事件觸發(fā)之前完成。

下面來(lái)進(jìn)行詳解的介紹這二者的區(qū)別。

一般情況

按照慣例,所有script元素都應(yīng)該放在頁(yè)面的head元素中。這種做法的目的就是把所有外部文件(CSS文件和JavaScript文件)的引用都放在相同的地方。可是,在文檔的head元素中包含所有JavaScript文件,意味著必須等到全部JavaScript代碼都被下載、解析和執(zhí)行完成以后,才能開(kāi)始呈現(xiàn)頁(yè)面的內(nèi)容(瀏覽器在遇到body標(biāo)簽時(shí)才開(kāi)始呈現(xiàn)內(nèi)容)。

對(duì)于那些需要很多JavaScript代碼的頁(yè)面來(lái)說(shuō),這無(wú)疑會(huì)導(dǎo)致瀏覽器在呈現(xiàn)頁(yè)面時(shí)出現(xiàn)明顯的延遲,而延遲期間的瀏覽器窗口中將是一片空白。為了避免這個(gè)問(wèn)題,現(xiàn)在Web應(yīng)用程序一般都全部JavaScript引用放在body元素中頁(yè)面的內(nèi)容后面。這樣一來(lái),在解析包含的JavaScript代碼之前,頁(yè)面的內(nèi)容將完全呈現(xiàn)在瀏覽器中。而用戶也會(huì)因?yàn)闉g覽器窗口顯示空白頁(yè)面的時(shí)間縮短而感到打開(kāi)頁(yè)面的速度加快了。

<!DOCTYPE html><html><head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title></head><body><script type="text/javascript" src="script.js"></script></body></html>

defer (延遲腳本)

延遲腳本:defer屬性只適用于外部腳本文件。

如果給script標(biāo)簽定義了defer屬性,這個(gè)屬性的作用是表明腳本在執(zhí)行時(shí)不會(huì)影響頁(yè)面的構(gòu)造。也就是說(shuō),腳本會(huì)被延遲到整個(gè)頁(yè)面都解析完畢后再運(yùn)行。因此,如果script元素中設(shè)置了defer屬性,相當(dāng)于告訴瀏覽器立即下載,但延遲執(zhí)行。

示例:

<!DOCTYPE html><html><head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>延遲加載</title> <script defer type="text/javascript" src="test.js"></script></head><body></body></html>

這個(gè)例子中,雖然我們把script元素放在了文檔的head元素中,但其中包含的腳本將延遲到瀏覽器遇到</html>標(biāo)簽后再執(zhí)行
HTML5規(guī)范要求腳本按照它們出現(xiàn)的先后順序執(zhí)行,因此第一個(gè)延遲腳本會(huì)先于第二個(gè)延遲腳本執(zhí)行,而這兩個(gè)腳本會(huì)先于DOMContentLoaded事件(在DOM樹(shù)構(gòu)建完成后觸發(fā),不需要等到所有的資源都加載完畢)執(zhí)行。

特別注意:在現(xiàn)實(shí)當(dāng)中,延遲腳本并不一定會(huì)按照順序執(zhí)行,也不一定會(huì)在DOMContentLoaded事件觸發(fā)前執(zhí)行,因此最好只包含一個(gè)延遲腳本。

有 defer,加載后續(xù)文檔元素的過(guò)程將和 script.js 的加載并行進(jìn)行(異步),但是 script.js 的執(zhí)行要在所有元素解析完成之后,DOMContentLoaded 事件觸發(fā)之前完成。

最佳實(shí)踐

從實(shí)用角度來(lái)說(shuō),把所有腳本都放在 </body> 之前是最佳實(shí)踐,因?yàn)閷?duì)于舊瀏覽器來(lái)說(shuō)這是唯一的優(yōu)化選擇,此法可保證非腳本的其他一切元素能夠以最快的速度得到加載和解析。

**注意:**defer屬性在瀏覽器之間表現(xiàn)并不一致。為了避免跨瀏覽器的差異,可以使用 “l(fā)azy loading”的方法,即直到用到該腳本時(shí)才加載。

function lazyload() { var elem = document.createElement("script"); elem.type = "text/javascript"; elem.async = true; elem.src = "script.js";  document.body.appendChild(elem);}if (window.addEventListener) { window.addEventListener("load", lazyload, false);} else if (window.attachEvent) { window.attachEvent("onload", lazyload);} else { window.onload = lazyload;}

async(異步腳本)

異步腳本:async屬性也只適用于外部腳本文件,并告訴瀏覽器立即下載文件。

但與defer不同的是:標(biāo)記為async的腳本并不保證按照指定它們的先后順序執(zhí)行。

<!DOCTYPE html><html><head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>異步加載</title> <script async type="text/javascript" src="test1.js"></script> <script async type="text/javascript" src="test2.js"></script></head><body></body></html>

這個(gè)例子中,test2.js可能會(huì)在test1.js之前執(zhí)行。因此,確保兩者之間互不一來(lái)非常重要。指定async屬性的目的是不讓頁(yè)面等待兩個(gè)腳本下載和執(zhí)行,從而異步加載頁(yè)面其他內(nèi)容。因此,建議異步腳本不要在加載期間修改DOM。

來(lái)看一張更加清晰的圖:

圖解:藍(lán)色線代表網(wǎng)絡(luò)讀取,紅色線代表執(zhí)行時(shí)間,這兩個(gè)都是針對(duì)腳本的;綠色線代表 HTML 解析。

通過(guò)上圖和之前的分析,我們可以得出:

      1、defer 和 async 在網(wǎng)絡(luò)讀取(腳本下載)這塊兒是一樣的,都是異步的(相較于 HTML 解析)

      2、兩者的差別:在于腳本下載完之后何時(shí)執(zhí)行,顯然 defer 是最接近我們對(duì)于應(yīng)用腳本加載和執(zhí)行的要求的。defer是立即下載但延遲執(zhí)行,加載后續(xù)文檔元素的過(guò)程將和腳本的加載并行進(jìn)行(異步),但是腳本的執(zhí)行要在所有元素解析完成之后,DOMContentLoaded 事件觸發(fā)之前完成。async是立即下載并執(zhí)行,加載和渲染后續(xù)文檔元素的過(guò)程將和js腳本的加載與執(zhí)行并行進(jìn)行(異步)。

      3、關(guān)于 defer,我們還要記住的是它是按照加載順序執(zhí)行腳本的

      4、標(biāo)記為async的腳本并不保證按照指定它們的先后順序執(zhí)行。對(duì)它來(lái)說(shuō)腳本的加載和執(zhí)行是緊緊挨著的,所以不管你聲明的順序如何,只要它加載完了就會(huì)立刻執(zhí)行。

      5、async 對(duì)于應(yīng)用腳本的用處不大,因?yàn)樗耆豢紤]依賴(哪怕是最低級(jí)的順序執(zhí)行),不過(guò)它對(duì)于那些可以不依賴任何腳本或不被任何腳本依賴的腳本來(lái)說(shuō)卻是非常合適的。

總結(jié)

以上就是關(guān)于js中defer和async區(qū)別的全部?jī)?nèi)容,文章介紹的很詳細(xì),希望能對(duì)大家的學(xué)習(xí)或者工作帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 梧州市| 务川| 安平县| 炉霍县| 德阳市| 溧水县| 杂多县| 大名县| 合阳县| 冀州市| 常熟市| 巨野县| 平顶山市| 沐川县| 吉隆县| 陆川县| 安福县| 耒阳市| 南安市| 馆陶县| 兴业县| 福清市| 宜君县| 五大连池市| 甘泉县| 钦州市| 永福县| 内乡县| 舒城县| 永丰县| 米泉市| 惠来县| 鄱阳县| 九江市| 顺平县| 麻栗坡县| 明光市| 衡阳市| 信阳市| 色达县| 吴川市|