關於對延遲腳本的思考
-
async
和defer
屬性的腳本,相信你們都據說過,可是他的真正執行細節是什麼樣子的?不多有文章認真研究它,可能不太有人注重細節,但其實真正有技術含量的工做和項目,對於性能要求極高,那麼細節就很重要了.須要不斷的實驗自我嘗試html -
最近幾個月,我一直在研究一些技術,例如
linux
,操做系統,算法等,預計要持續學習到今年年末。紅寶書第四版出來後,我也是花了不少時間去看。對於延遲腳本,本身也是作了一個實驗,寫下了這篇總結前端
什麼是延遲腳本?
-
script
標籤,帶async
和defer
屬性等,經過document.createElement('script')
建立而且沒有指定script.async=false
的腳本默認爲異步延遲
腳本(必須爲非內聯腳本),以下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script src="./async1.js" async></script>
<script src="./async2.js" async></script>
<script src="./defer1.js" defer></script>
<script src="./defer2.js" defer></script>
<script src="./common1.js"></script>
<script src="./common2.js"></script>
<script src="./common3.js"></script>
</html>
-
以上7個腳本文件,其中 common
開頭爲非異步延遲腳本,其他的都指定了延遲腳本的模式,分爲async
和defer
兩種
經過document.createElement建立的標籤插入默認爲
async
模式linux
開始實驗
![](http://static.javashuo.com/static/loading.gif)
-
我一共寫了2個
async
和2個defer
標籤,其它的都是普通標籤.其中async1.js
裏面有4000行代碼,其它都是一個console.log
而已web -
第一次實驗結果:算法
![](http://static.javashuo.com/static/loading.gif)
-
再次刷新頁面(注意我已經禁用了瀏覽器緩存),結果爲:
![](http://static.javashuo.com/static/loading.gif)
-
再次刷新,發現 async
執行時機和順序不肯定,可是能肯定defer
確定在async
以後執行。
![](http://static.javashuo.com/static/loading.gif)
緣由在於:
async
是告訴瀏覽器,能夠沒必要等到它下載解析完後再加載頁面,也不用等它執行完後再執行其餘腳本,俗稱異步執行腳本
瀏覽器
看下載執行時機和打印結果的對比
-
打印結果:
![](http://static.javashuo.com/static/loading.gif)
-
對應的下載執行時機
![](http://static.javashuo.com/static/loading.gif)
-
從上面看,下載時機 async
和普通模式都是一樣並行下載,只有defer是最後才下載(http1.1有併發數量限制
,但是這裏並非併發限制,當我刪除common
的引用後,我發現defer
永遠都是最後下載的)
![](http://static.javashuo.com/static/loading.gif)
-
async
和defer
兩種模式,區別在於: -
async
是告訴瀏覽器,它不會操做dom
,能夠沒必要等到它下載解析完後再加載頁面,也不用等它執行完後再執行其餘腳本,俗稱異步執行腳本
, 多個async
沒法保證他們的執行順序,例如async1
和async2
沒法按順序執行 -
defer
是在解析到結束到</html>
標籤後纔會執行,俗稱推遲執行腳本
,多個defer
能夠按順序執行,例如defer1
和defer2
能夠按順序執行(實際上也不保證順序執行) -
解析到 script
標籤後,async
是直接下載 -
解析到 script
標籤後,defer
是最後下載 -
相同點: -
多個 async
或者defer
標籤實際上都不能保證順序執行 -
都不會阻塞解析其餘 script
標籤內容的解析和頁面渲染 -
他們都會在瀏覽器 load
事件前執行,可是不保證是在DomContentLoad
事件前仍是後執行 -
defer
確定在async
後面執行,從個人實驗結果和書上對它們對解析來看
影響多個異步腳本的執行順序因素
-
腳本文件大小 -
網絡傳輸因素
特殊狀況
-
當全部的腳本文件都很小很小的時候,結果會在很大機率穩定在
![](http://static.javashuo.com/static/loading.gif)
使用的注意點
-
異步推遲腳本的執行順序並不穩定,全部儘可能只有一個 -
使用異步推遲腳本時,應該考慮什麼場景才使用,而不是濫用它
寫在最後
-
紙上得來終覺淺,欲知此事要躬行,我寫得也不必定對,若是你有問題或者更好的答案能夠在下面參與討論,我始終認爲有爭議和反對的聲音是好事 -
另外你若是以爲寫得不錯對你有幫助,能夠幫忙點個 在看/贊/關注
. -
關注 前端巔峯
公衆號後回覆:加羣
,便可加羣獲取3800G
免費前端學習視頻資源
-
本文分享自微信公衆號 - 前端巔峯(Java-Script-)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。緩存