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 属性的影响,这是另外一个故事。
浏览器在迅速发展,不少总结,特别是书籍上的,很难与时俱进。你们应该像克军学习,多测试,多发现,这样得来的知识,才不会过期。这篇博客的总结,也确定在将来甚至就在如今,已经存在错误。这些都无所谓,关键是要懂得测试的方法和分析的思路,有了“渔”,才能更好地探求和拥有“鱼”。