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

标签: javascript css 响应速度 效率 | 发表时间:2014-12-29 10:24 | 作者:Aomine
出处:http://segmentfault.com/blogs

克军做了一系列测试: 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 属性的影响,这是另一个故事。

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

转自 岁月如歌

相关 [js css 位置] 推荐:

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

- - SegmentFault 最新的文章
克军做了一系列测试: js和css的顺序关系,给出了现象和结论,但未给出原因. JS 和 CSS 在页面中的位置,会影响其他资源(指 img 等非 js 和 css 资源)的加载顺序,究其原因,有三个值得注意的点:. JS 有可能会修改 DOM.典型的,可能会有. 这意味着,在当前 JS 加载和执行完成前,后续所有资源的下载有可能是没必要的.

在线调试并共享HTML,CSS,JS

- Albert - [米随随] s5s5
如题,以后同人讲代码时可以用到. 2004年04月9日 -- MSN中文专业站 (0). 2006年06月5日 -- 读“疲倦的博客们”有感 (9). 2005年07月20日 -- 基于web2.0的网站创意 (33).

[html/css/js]搜索建议提示

- - CSDN博客推荐文章
// 根据id获取dom元素. // 将label绑定到input上作为输入提示. // 获取输入焦点时,隐藏提示标签. // 失去输入焦点时,判断输入框的是否有值,有则显示提示标签. // 窗口加载完dom结构时. .

js和css的顺序关系

- - Kejun's Blog
head里的顺序如下,考虑会对请求有何影响:. a,b – head里出现外联js,无论如何放,css文件都不能和body里的请求并行 (图1). c – head里的内联js只要在所有外联css前面,css文件可以和body里的请求并行(图2). d – head里的内联js只要在任一外联css后面,css文件就不能和body里的请求并行(图1).

用javascript预加载图片、css、js的方法研究

- - 博客园_Ruby's Louvre
预加载的好处可以让网页更快的呈现给用户,缺点就是可能会增加无用的请求(但图片、css、js这些静态文件可以被缓存),如果用户访问的页面里面的 css、js、图片被预加载了,用户打开页面的速度会快很多,提升用户体验. 在用到一些大图片展示的时候,预加载大图是很不错的方法,图片更快的被呈现给用户. 不多说了,作为一个前端攻城师都懂的,下面分享我做的测试和得到的结果.

收集免费的HTML/CSS/JS UI工具包

- - Jackchen Design 1984
随着HTML5和CSS3以及网页设计布局的全面翻新创新改革. 让很多网页设计者和界面设计师都知道一个道理. 这不仅仅是未来提高工作的效率,还能更好的去处理网页整体视觉效果. 优秀的工具包可以让您的工作事半功倍是肯定. 重要的是可以让流程更加清晰快速的呈现出来. 所以对于很多好的网站(比如Facebook,twitter,YaHOO等)你看第一眼就能知道他们所属的风格指向.

Ratchet:使用 HTML,JS,CSS 创建 iPhone App 原型

- - 我爱水煮鱼
Ratchet 是一个免费的开源的工具,它主要的功能就是可以使用最简单的 HTML,CSS,JavaScript 这些 Web 技术就能很容易创建 iPhone 应用原型. Ratchet 使用非常简单,只需要简单的几行代码就能创建绝大部分 iOS 的组件,如:Bars, Lists, Buttons, Segmented controllers, Counts, Forms, Toggles, Popovers, Sliders, Push 等等.

100个惊人的CSS、JS代码技术

- - 设计达人
最近在Codepen看到Top Pens of 2013这个专题,专题内容为2013年上最优秀的前100个CSS、HTML5和Javascript Pens,在惊叹技术人员的创造力同时我们还能学习这些技术,对交互设计师而言还能获取灵感哦. Top Pens of 2013专题地址: http://codepen.io/2013/popular.

css固定元素位置(fixed)

- - Web前端 - ITeye博客
我们经常碰到的需求是希望页面某个元素固定在浏览器的一个位置,无论如何滚动滚动条,位置不变,就例如经常看到的弹出广告. 方法一般是使用js控制,或者使用css. 在IE7以上版本及firefox、opera、safari里,都支持css属性"position:fixed",它的作用就是将元素相对于窗口固定位置.

CSSでカーニング(文字詰め)等を可能にするJSライブラリ・kerning.js

- 三十不归 - かちびと.net
ゆっくり過ごす方も多そうですね. さて、休みですし、ちょっとネタ的. をCSSで出来るようにしたJSライブラ. jQueryやmootoolsなどにも依存していないようです. これだけ聞くとかなり使えそうなんですけど. でも個人的にこういうチャレンジは称えたいので敬意を示すつもりで記事にします. CSSで出来る、と言っても独自の記述法を加える事でテキストコンテンツでのカーニングを実現するタイプなので好みが分かれそうですね.