JS 和 CSS 的位置对其他资源加载顺序的影响

转载 2015年11月18日 19:08:46

http://segmentfault.com/a/1190000002450735

克军做了一系列测试:js和css的顺序关系,给出了现象和结论,但未给出原因。

JS 和 CSS 在页面中的位置,会影响其他资源(指 img 等非 js 和 css 资源)的加载顺序,究其原因,有三个值得注意的点:

  1. JS 有可能会修改 DOM.典型的,可能会有 document.write. 这意味着,在当前 JS 加载和执行完成前,后续所有资源的下载有可能是没必要的。这是 JS 阻塞后续资源下载的根本原因。
  2. JS 的执行有可能依赖最新样式。比如,可能会有 var width = $('#id').width(). 这意味着,JS 代码在执行前,浏览器必须保证在此 JS 之前的所有 css(无论外链还是内嵌)都已下载和解析完成。这是 CSS 阻塞后续 JS 执行的根本原因。
  3. 现代浏览器很聪明,会进行 prefetch 优化。性能是如此重要,现代浏览器在竞争中,在 UI update 线程之外,还会开启另一个线程,对后续 JS 和 CSS 提前下载(注意,仅提前下载,并不执行)。有了 prefetch 优化,这意味着,在不存在任何阻塞的情况下,理论上 JS 和 CSS 的下载时机都非常优先,和位置无关。

以上三点可简述为三条基本定律:

  • 定律一:资源是否下载依赖 JS 执行结果。
  • 定律二:JS 执行依赖 CSS 最新渲染。
  • 定律三:现代浏览器存在 prefetch 优化。

有了这三条定律,再来看克军的测试,就很清晰了:

a,b – head里出现外联js,无论如何放,css文件都不能和body里的请求并行

根据定律一和定律三,可以知道上面的结论不够正确。比如:

<head>
<link rel="stylesheet" href="mock.php?css1&sleep=2">
<script src="mock.php?js&sleep=3"></script>
<link rel="stylesheet" href="mock.php?css2&sleep=4">
</head>
<body>
<link rel="stylesheet" href="mock.php?css3&sleep=5">
<img src="test.gif">
</body>

在 Chrome 下的瀑布图是:

黄色条是 js 的,可以看出 img 的延时下载是由定律一决定的。

定律三则决定了所有 js/css 都是并行开始下载的。在 Firefox 10 下,prefetch 非常强悍,对 img 也会预加载,瀑布图如下:

调整一下 sleep 时间,还可以观察到定律二的威力:

<head>
<link rel="stylesheet" href="mock.php?css1&sleep=3"> <!-- 修改 sleep 值,使其大于 js 的 -->
<script src="mock.php?js&sleep=2"></script>
<link rel="stylesheet" href="mock.php?css2&sleep=4">
</head>
<body>
<link rel="stylesheet" href="mock.php?css3&sleep=5">
<img src="test.gif">
</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 属性的影响,这是另一个故事。

浏览器在迅速发展,很多总结,特别是书籍上的,很难与时俱进。大家应该像克军学习,多测试,多发现,这样得来的知识,才不会过时。这篇博客的总结,也肯定在未来甚至就在现在,已经存在错误。这些都无所谓,关键是要懂得测试的方法和分析的思路,有了“渔”,才能更好地探求和拥有“鱼”


html,css,js加载顺序

html,css,js加载顺序
  • aquial
  • aquial
  • 2017年05月21日 00:28
  • 584

页面js和css加载顺序优化建议

body里dom渲染取决于head里的外联js加载完。 根据此原理,建议如下: 1、head里出现外联js,无论如何放,css文件都不能和body里的请求并行。 2、head里面...
  • kaosini
  • kaosini
  • 2014年05月28日 16:00
  • 965

CSS的float属性对周围元素位置的影响

float属性定义了元素可以往哪个方向浮动,float常见的值有: left 元素向左浮动。 right 元素向右浮动。 none 默认值。元素不浮动,并会显示在其在文本中出现的...
  • Crystal_wxj
  • Crystal_wxj
  • 2017年02月19日 09:41
  • 1045

JS 和 CSS 的位置对其他资源加载顺序的影响

克军做了一系列测试:js和css的顺序关系,给出了现象和结论,但未给出原因。 JS 和 CSS 在页面中的位置,会影响其他资源(指 img 等非 js 和 css 资源)的加载顺序,究其原因,有三个...
  • zlklove1234
  • zlklove1234
  • 2015年01月07日 16:42
  • 179

CSS、JS 放置位置与前端性能的关系?

Q: 问这个问题之前,我先说一下浏览器的解析方式,浏览器解析html页面首先浏览器先下载html,然后在内存中把html代码转化成Dom Tree, 然后浏览器根据Dom Tree上的Node分析cs...
  • bigtree_3721
  • bigtree_3721
  • 2016年03月29日 15:12
  • 989

html、css、js加载顺序

浏览器加载和渲染html的顺序 1. IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的。 2. 在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联...
  • for_cxc
  • for_cxc
  • 2016年01月09日 16:05
  • 6258

web测试需要了解的知识

这里只是介绍Web测试相对于其他类型软件的测试额外需要了解的内容,关于测试方法不是本文的重点,里面谈到的每一项在以后的文章中再说明。大家看到这些内容可能都不陌生,我晒出的内容也许不对或有误导,请大家指...
  • aoshilang2249
  • aoshilang2249
  • 2016年10月24日 15:02
  • 252

html、css、js文件加载顺序及执行情况

html、css、js文件加载顺序及执行情况
  • muguli2008
  • muguli2008
  • 2016年09月26日 10:29
  • 1293

jsp页面中html,javascript.css的执行顺序

其实浏览器加载显示html的顺序是按下面的顺序进行的: 1、IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的。 2、在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并...
  • bigtree_3721
  • bigtree_3721
  • 2016年03月29日 14:48
  • 1315

css中的定位对其他元素的影响

1.相信初学者在刚刚接触定位,并且使用固定定位的时候,可能会出现一些不是自己想要的那个效果,使用固定定位的元素会影响到显示在它下方的元素,下方的元素会被使用固定定位的元素覆盖掉固定定位元素的高度。下面...
  • qq_39585562
  • qq_39585562
  • 2017年08月03日 23:21
  • 232
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JS 和 CSS 的位置对其他资源加载顺序的影响
举报原因:
原因补充:

(最多只允许输入30个字)