H5 資源異步加載策略

1、async & defer

  • 區別
    async異步加載腳本,加載完立馬執行
    defer異步加載腳本,并在DOMContentLoaded之前執行,若有多個,按照加載順序執行腳本;async 對于應用腳本的用處不大,因為它完全不考慮依賴(哪怕是最低級的順序執行),不過它對于那些可以不依賴任何腳本或不被任何腳本依賴的腳本來說卻是非常合適的
執行過程
  • 兼容性
async
defer
  • 使用建議
    1、defer更適合做異步加載,因為其考慮了腳本依賴,并在DOMContentLoaded之前執行;
    2、async不考慮腳本依賴,加載完會立即執行,執行期間還會阻塞DOM解析,只適用不依賴任何腳本或不被任何腳本依賴的腳本;
    3、瀏覽器遇到 <script>且沒有defer或async屬性的標簽時,會觸發頁面渲染,因而如果前面CSS資源尚未加載完畢時,瀏覽器會等待它加載完畢再執行腳本,因此若js文件放頭部,最好放css前面或加上defer/async

2、preload & dns-prefetch

(目前移動端支持度并不好,僅作參考)
DNS prefetching通過指定具體的URL來告知客戶端未來會用到相關的資源,這樣瀏覽器可以盡早的解析DNS。比如我們需要一個在example.com的圖片或者視頻文件。在<head>就可以這么寫:

<link rel="dns-prefetch" >

項目中有用到第三方的代碼時這么做尤其有益(其他的使用場景,比如當靜態資源和HTML不在一個域上,而在CDN上;又比如在重定向前可以加上DNS prefetch)

3、資源阻塞及加載優先級

  • 有3種原因會阻止頁面加載資源,包括CSP、Mixed Content、Origin block,CSP是自己手動設置的一些限制,Mixed Content是https頁面不允許加載http的內容,Origin Block主要是svg的href只能是同源的資源。
//只允許加載自己域的圖片,否則報錯
<meta http-equiv="Content-Security-Policy" content="img-src 'self';">
//將網頁的http請求強制升級為https
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
//在https的網站請求http的內容就是Mixed Content,例如加載一個http的JS腳本,這種請求通常會被瀏覽器堵塞掉,有幾種資源屬于可選阻塞:audio,vedio,favicon,image即瀏覽器默認可以在https下加載http開頭的這幾種資源,但是當設置了以下meta時,所有http資源都無法在https下得到加載(image的srcset屬性不算可選阻塞,src屬性算)。而對于主動混合內容,如果用戶設置允許加載也是可以加載的
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
//Origin Block主要是svg使用use獲取svg資源的時候必須不能跨域
  • 資源優先級


    優先級
<!DOCType html>
<html>
<head>
    <meta charset="utf-8">
    <link rel="icon" href="4.png">
    <img src="0.png">
    <img src="1.png">
    <link rel="stylesheet" href="1.css">
    <link rel="stylesheet" href="2.css">
    <link rel="stylesheet" href="3.css">
    <link rel="stylesheet" href="4.css">
    <link rel="stylesheet" href="5.css">
    <link rel="stylesheet" href="6.css">
    <link rel="stylesheet" href="7.css">
</head>
<body>
    <p>hello</p>
    <img src="2.png">
    <img src="3.png">
    <img src="4.png">
    <img src="5.png">
    <img src="6.png">
    <img src="7.png">
    <img src="8.png">
    <img src="9.png">

    <script src="1.js"></script>
    <script src="2.js"></script>
    <script src="3.js"></script>

    <img src="3.png">
<script>
!function(){
    let xhr = new XMLHttpRequest();
    xhr.open("GET", "https://baidu.com");
    xhr.send();
    document.write("hi");
}();
</script>
<link rel="stylesheet" href="9.css">
</body>
</html>

這個html資源加載timeline如下:


timeline

解釋1:
(1)每個域每次最多同時加載6個資源(http/1.1)

(2)CSS具有最高的優先級,最先加載,即使是放在最后面9.css也是比前面資源先開始加載

(3)JS比圖片優先加載,即使出現得比圖片晚

(4)只有等CSS都加載完了,才能加載其它的資源,即使這個時候沒有達到6個的限制

(5)head里面的非高優化級的資源最多能先加載一張(0.png)

(6)xhr的資源雖然具有高優先級,但是由于它是排在3.js后面的,JS的執行是同步的,所以它排得比較靠后,如果把它排在1.js前面,那么它也會比圖片先加載。
解釋2:
(1)高優先級的資源(>=Medium)、同步請求和非http(s)的請求能夠立刻加載

(2)只要有一個layout blocking的資源在加載,最多只能加載一個delayable的資源,這個就解釋了為什么0.png能夠先加載

(3)只有當layout blocking和high priority的資源加載完了,才能開始加載delayable的資源,這個就解釋了為什么要等CSS加載完了才能加載其它的js/圖片。

(4)同時加載的delayable資源同一個域只能有6個,同一個client即同一個頁面最多只能有10個,否則要進行排隊。
解釋3:
白色條是指queue的時間段,而灰色的是已經in flight了但受到同域只能最多只能建立6個TCP連接等的影響而進入的stalled狀態,綠色是TTFB(Time to First Byte)從開始建立TCP連接到收到第一個字節的時間,藍色是下載的時間。

我們已經解釋了大部分加載的特點的原因,對著上面那張圖可以再重述一次:
(1)由于1.css到9.css這幾個CSS文件是high priority或者是none delayable的,所以馬上in flight,但是還受到了同一個域最多只能有6個的限制,所以6/7/9.css這三個進入stalled的狀態

(2)1.css到5.css是layout-blocking的,所以最多只能再加載一個delayable的0.png,在它相鄰的1.png就得排隊了

(3)等到high priority和layout-blocking的資源7.css/9.css/1.js加載完了,就開始加載delayable的資源,主要是preload的js和圖片

4、參考

【1】從Chrome源碼看瀏覽器如何加載資源

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,003評論 2 374

推薦閱讀更多精彩內容

  • 簡單介紹JavaScript的發展歷史 JavaScript因互聯網而生,回顧它的歷史要從瀏覽器的歷史講起。 19...
    _Dot912閱讀 503評論 0 3
  • 本文總結一下瀏覽器在 javascript 的加載方式。關鍵詞:異步加載(async loading),延遲加載(...
    4ea0af17fd67閱讀 1,068評論 0 2
  • 在線閱讀 http://interview.poetries.top[http://interview.poetr...
    前端進階之旅閱讀 114,526評論 24 450
  • 前端開發面試知識點大綱: HTML&CSS: 對Web標準的理解、瀏覽器內核差異、兼容性、hack、CSS基本功:...
    秀才JaneBook閱讀 2,419評論 0 25
  • 常見試題 行內元素:會在水平方向排列,不能包含塊級元素,設置width無效,height無效(可以設置line-h...
    他大舅啊閱讀 2,465評論 1 5