JS 和 CSS 在頁面中的位置,會影響其餘資源(指 img 等非 js 和 css 資源)的加載順序,究其緣由,有三個值得注意的點:php
document.write
. 這意味着,在當前 JS 加載和執行完成前,後續全部資源的下載有多是不必的。這是 JS 阻塞後續資源下載的根本緣由。var width = $('#id').width()
. 這意味着,JS 代碼在執行前,瀏覽器必須保證在此 JS 以前的全部 css(不管外鏈仍是內嵌)都已下載和解析完成。這是 CSS 阻塞後續 JS 執行的根本緣由。以上三點可簡述爲三條基本定律:css
有了這三條定律,再來看克軍的測試,就很清晰了:css3
a,b – head裏出現外聯js,不管如何放,css文件都不能和body裏的請求並行瀏覽器
根據定律一和定律三,能夠知道上面的結論不夠正確。好比:async
1 |
<head> |
2 |
<link rel="stylesheet" href="mock.php?css1&sleep=2"> |
3 |
<script src="mock.php?js&sleep=3"></script> |
4 |
<link rel="stylesheet" href="mock.php?css2&sleep=4"> |
5 |
</head> |
6 |
<body> |
7 |
<link rel="stylesheet" href="mock.php?css3&sleep=5"> |
8 |
<img src="test.gif"> |
9 |
</body> |
在 Chrome 下的瀑布圖是:性能
黃色條是 js 的,能夠看出 img 的延時下載是由定律一決定的。學習
定律三則決定了全部 js/css 都是並行開始下載的。在 Firefox 10 下,prefetch 很是強悍,對 img 也會預加載,瀑布圖以下:測試
調整一下 sleep 時間,還能夠觀察到定律二的威力:fetch
1 |
<head> |
2 |
<link rel="stylesheet" href="mock.php?css1&sleep=3"> <!-- 修改 sleep 值,使其大於 js 的 --> |
3 |
<script src="mock.php?js&sleep=2"></script> |
4 |
<link rel="stylesheet" href="mock.php?css2&sleep=4"> |
5 |
</head> |
6 |
<body> |
7 |
<link rel="stylesheet" href="mock.php?css3&sleep=5"> |
8 |
<img src="test.gif"> |
9 |
</body> |
瀑布圖馬上發生了變化:優化
由於定律一,決定 img 的下載在 js 執行後。又由於定律二,決定 js 的執行在第一個 css 後。因而最後在瀑布圖上體現出來,就是 img 的下載在第一個 css 後。
再來看克軍的第二個結論:
c – head裏的內聯js只要在全部外聯css前面,css文件能夠和body裏的請求並行(圖2)
d – head裏的內聯js只要在任一外聯css後面,css文件就不能和body裏的請求並行(圖1)
這個是定律二的威力。結論 c 是正確的,由於沒有 css 會影響 js 的執行。結論 d 則不夠正確。img 等其餘資源,會在 js 前面的 css 下載完成後,以及 js 執行後,馬上開始下載。與頭部中,js 位置以後的 css 不要緊。
克軍的其餘結論都是對的,很少說。
注意1:Firefox 10 的 prefetch 有點奇怪,有時會對 img 進行 prefetch,有時則不會。有興趣的能夠進一步尋找規律。
注意2:上面的三個定律,是黑盒猜想,有興趣的能夠去閱讀瀏覽器的源碼,應該能找到更深層次的緣由。
注意3:本文沒有考慮 defer, async 屬性的影響,這是另外一個故事。
瀏覽器在迅速發展,不少總結,特別是書籍上的,很難與時俱進。你們應該像克軍學習,多測試,多發現,這樣得來的知識,纔不會過期。這篇博客的總結,也確定在將來甚至就在如今,已經存在錯誤。這些都無所謂,關鍵是要懂得測試的方法和分析的思路,有了「漁」,才能更好地探求和擁有「魚」。