麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > JavaScript > 正文

淺析script標(biāo)簽中的defer與async屬性

2019-11-19 18:45:41
字體:
供稿:網(wǎng)友

一、前言

看到的前輩寫的代碼如下

<script src="#link("xxxx/xx/home/home.js")" type="text/javascript" async defer></script>

竟然同時有asyncdefer屬性,心想著肯定是前輩老司機(jī)的什么黑科技,兩個一塊兒肯定會發(fā)生什么神奇化學(xué)反應(yīng),于是趕緊懷著一顆崇敬的心去翻書翻文檔,先復(fù)習(xí)一下各自的定義。

二、調(diào)查一番

先看看asyncdefer各自的定義吧,翻開紅寶書望遠(yuǎn)鏡,是這么介紹的

2.1 defer

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

HTML5規(guī)范要求腳本按照它們出現(xiàn)的先后順序執(zhí)行,因此第一個延遲腳本會先于第二個延遲腳本執(zhí)行,而這兩個腳本會先于DOMContentLoaded事件執(zhí)行。在現(xiàn)實(shí)當(dāng)中,延遲腳本并不一定會按照順序執(zhí)行,也不一定會在DOMContentLoad時間觸發(fā)前執(zhí)行,因此最好只包含一個延遲腳本。

2.2 async

這個屬性與defer類似,都用于改變處理腳本的行為。同樣與defer類似,async只適用于外部腳本文件,并告訴瀏覽器立即下載文件。但與defer不同的是,標(biāo)記為async的腳本并不保證按照它們的先后順序執(zhí)行。

第二個腳本文件可能會在第一個腳本文件之前執(zhí)行。因此確保兩者之間互不依賴非常重要。指定async屬性的目的是不讓頁面等待兩個腳本下載和執(zhí)行,從而異步加載頁面其他內(nèi)容。

概括來講,就是這兩個屬性都會使script標(biāo)簽異步加載,然而執(zhí)行的時機(jī)是不一樣的。引用segmentfault上的一個回答中的一張圖

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

也就是說async是亂序的,而defer是順序執(zhí)行,這也就決定了async比較適用于百度分析或者谷歌分析這類不依賴其他腳本的庫。從圖中可以看到一個普通的<script>標(biāo)簽的加載和解析都是同步的,會阻塞DOM的渲染,這也就是我們經(jīng)常會把<script>寫在<body>底部的原因之一,為了防止加載資源而導(dǎo)致的長時間的白屏,另一個原因是js可能會進(jìn)行DOM操作,所以要在DOM全部渲染完后再執(zhí)行。

2.3 really?

然而,這張圖(幾乎是百度搜到的唯一答案)是不嚴(yán)謹(jǐn)?shù)模@只是規(guī)范的情況,大多數(shù)瀏覽器在實(shí)現(xiàn)的時候會作出優(yōu)化。

來看看chrome是怎么做的

《WebKit技術(shù)內(nèi)幕》:

      1、當(dāng)用戶輸入網(wǎng)頁URL的時候,WebKit調(diào)用其資源加載器加載該URL對應(yīng)的網(wǎng)頁。

      2、加載器依賴網(wǎng)絡(luò)模塊建立連接,發(fā)送請求并接受答復(fù)。

      3、WebKit接收到各種網(wǎng)頁或者資源的數(shù)據(jù),其中某些資源可能是同步或異步獲取的。

      4、網(wǎng)頁被交給HTML解釋器轉(zhuǎn)變成一系列的詞語(Token)。

      5、解釋器根據(jù)詞語構(gòu)建節(jié)點(diǎn)(Node),形成DOM樹。

      6、如果節(jié)點(diǎn)是JavaScript代碼的話,調(diào)用JavaScript引擎解釋并執(zhí)行。

      7、JavaScript代碼可能會修改DOM樹的結(jié)構(gòu)。

      8、如果節(jié)點(diǎn)需要依賴其他資源,例如圖片、CSS、視頻等,調(diào)用資源加載器來加載他們,但是他們是異步的,不會阻礙當(dāng)前DOM樹的繼續(xù)創(chuàng)建;如果是JavaScript資源URL(沒有標(biāo)記異步方式),則需要停止當(dāng)前DOM樹的創(chuàng)建,直到JavaScript的資源加載并被JavaScript引擎執(zhí)行后才繼續(xù)DOM樹的創(chuàng)建。

所以,通俗來講,chrome瀏覽器首先會請求HTML文檔,然后對其中的各種資源調(diào)用相應(yīng)的資源加載器進(jìn)行異步網(wǎng)絡(luò)請求,同時進(jìn)行DOM渲染,直到遇到<script>標(biāo)簽的時候,主進(jìn)程才會停止渲染等待此資源加載完畢然后調(diào)用V8引擎對js解析,繼而繼續(xù)進(jìn)行DOM解析。我的理解如果加了async屬性就相當(dāng)于單獨(dú)開了一個進(jìn)程去獨(dú)立加載和執(zhí)行,而defer是和將<script>放到<body>底部一樣的效果。

三、實(shí)驗一發(fā)

3.1 demo

為了驗證上面的結(jié)論我們來測試一下

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <link  rel="stylesheet"> <link  rel="stylesheet"> <script src="http://lib.sinaapp.com/js/angular.js/angular-1.2.19/angular.js"></script> <script src="http://libs.baidu.com/backbone/0.9.2/backbone.js"></script> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script></head><body> ul>li{這是第$個節(jié)點(diǎn)}*1000</body></html>

一個簡單的demo,從各個CDN上引用了2個CSS3個JS,在body里面創(chuàng)建了1000個li。通過調(diào)整外部引用資源的位置和加入相關(guān)的屬性利用chrome的Timeline進(jìn)行驗證。

3.2 放置在<head>內(nèi)

異步加載資源,但會阻塞<body>的渲染會出現(xiàn)白屏,按照順序立即執(zhí)行腳本

3.3 放置在<body>底部


異步加載資源,等<body>中的內(nèi)容渲染完畢后且加載完按順序執(zhí)行JS

3.3 放置在<head>頭部并使用async

異步加載資源,且加載完JS資源立即執(zhí)行,并不會按順序,誰快誰先上

3.4 放置在<head>頭部并使用defer


異步加載資源,在DOM渲染后之后再按順序執(zhí)行JS

3.5 放置在<head>頭部并同時使用async和defer


表現(xiàn)和async一致,開了個腦洞,把這兩個屬性交換一下位置,看會不會有覆蓋效果,結(jié)果發(fā)現(xiàn)是一致的 = =、

綜上,在webkit引擎下,建議的方式仍然是把<script>寫在<body>底部,如果需要使用百度谷歌分析或者不蒜子等獨(dú)立庫時可以使用async屬性,若你的<script>標(biāo)簽必須寫在<head>頭部內(nèi)可以使用defer屬性

四、 兼容性

那么,揣摩一下前輩的心理,同時寫上的原因是什么呢,兼容性?

上caniuse,async在IE<=9時不支持,其他瀏覽器OK;defer在IE<=9時支持但會有bug,其他瀏覽器OK;現(xiàn)象在這個issue里有描述,這也就是“望遠(yuǎn)鏡”里建議只有一個defer的原因。所以兩個屬性都指定是為了在async不支持的時候啟用defer,但defer在某些情況下還是有bug。

The defer attribute may be specified even if the async attribute is specified, to cause legacy Web browsers that only support defer (and not async) to fall back to the defer behavior instead of the synchronous blocking behavior that is the default.

五、結(jié)論

其實(shí)這么講來,最穩(wěn)妥的辦法還是把<script>寫在<body>底部,沒有兼容性問題,沒有白屏問題,沒有執(zhí)行順序問題,高枕無憂,不要搞什么deferasync的花啦~

目前只研究了chrome的webkit的渲染機(jī)制,F(xiàn)irefox和IE的有待繼續(xù)研究,圖片和CSS以及其他外部資源的渲染有待研究。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 一级空姐毛片 | 毛片在哪看 | 91av日韩| 免费专区 - 91爱爱 | 国产一级淫片免费看 | 久久草在线观看视频 | 成人国产在线看 | 综合毛片 | 免费黄色小视频网站 | www.17c亚洲蜜桃 | 久草在线视频在线 | 在线观看视频毛片 | 嗯~啊~用力~高h | 国产羞羞视频 | 精品国产一区二区三区四 | 欧美乱淫 | 色成人在线| 人人看人人舔 | 中文字幕在线视频网站 | 国产亚色| 72pao成人国产永久免费视频 | 欧美日韩在线视频一区 | 5a级毛片 | omofun 动漫在线观看 | 久久99综合| 中文字幕激情视频 | 草草久久久| 成人免费在线视频播放 | 91美女啪啪| 男男羞羞视频网站国产 | 国产精选久久久 | 黄色电影免费提供 | 2019亚洲日韩新视频 | 色综合网在线观看 | 杏美月av| 成人免费激情视频 | 最新av网址在线观看 | 国产精品自拍啪啪 | 国产一级一级片 | 成人国产精品免费 | 毛片在哪里看 |