在无数地方在线我见过的建议,包括在 JavaScript 的 CSS。理由是一般来说,这种形式:

订购您的 CSS 和 JavaScript 时,您希望您的 CSS 要放在前面。原因是呈现线程已呈现的页所需的所有样式信息。如果 JavaScript 包括第一,靠的 JavaScript 引擎必须分析其所有然后再继续下一组资源。这意味着呈现线程无法完全显示该页,因为它不存在它所需要的所有样式。

我实际测试中发现非常不同的地方︰

测试工具

我使用下面的 Ruby 脚本生成各种资源特定的延迟︰

require 'rubygems'
require 'eventmachine'
require 'evma_httpserver'
require 'date'

class Handler  < EventMachine::Connection
  include EventMachine::HttpServer

  def process_http_request
    resp = EventMachine::DelegatedHttpResponse.new( self )

    return unless @http_query_string

    path = @http_path_info
    array = @http_query_string.split("&").map{|s| s.split("=")}.flatten
    parsed = Hash[*array]

    delay = parsed["delay"].to_i / 1000.0
    jsdelay = parsed["jsdelay"].to_i

    delay = 5 if (delay > 5)
    jsdelay = 5000 if (jsdelay > 5000)

    delay = 0 if (delay < 0) 
    jsdelay = 0 if (jsdelay < 0)

    # Block which fulfills the request
    operation = proc do
      sleep delay 

      if path.match(/.js$/)
        resp.status = 200
        resp.headers["Content-Type"] = "text/javascript"
        resp.content = "(function(){
            var start = new Date();
            while(new Date() - start < #{jsdelay}){}
          })();"
      end
      if path.match(/.css$/)
        resp.status = 200
        resp.headers["Content-Type"] = "text/css"
        resp.content = "body {font-size: 50px;}"
      end
    end

    # Callback block to execute once the request is fulfilled
    callback = proc do |res|
        resp.send_response
    end

    # Let the thread pool (20 Ruby threads) handle request
    EM.defer(operation, callback)
  end
end

EventMachine::run {
  EventMachine::start_server("0.0.0.0", 8081, Handler)
  puts "Listening..."
}

上述微型服务器可以设置任意延迟的 JavaScript 文件 (服务器和客户端) 和任意 CSS 延迟。例如, http://10.0.0.50:8081/test.css?delay=500给了我 500 毫秒延迟传输 CSS。

我使用以下页面来测试。

<!DOCTYPE html>
<html>
  <head>
      <title>test</title>
      <script type='text/javascript'>
          var startTime = new Date();
      </script>
      <link href="http://10.0.0.50:8081/test.css?delay=500" type="text/css" rel="stylesheet">
      <script type="text/javascript" src="http://10.0.0.50:8081/test2.js?delay=400&amp;jsdelay=1000"></script> 
  </head>
  <body>
    <p>
      Elapsed time is: 
      <script type='text/javascript'>
        document.write(new Date() - startTime);
      </script>
    </p>    
  </body>
</html>

当我第一次包含 CSS 时,页面需要花费 1.5 秒呈现︰

CSS first

当我第一次包含 JavaScript 时,页面需要花费 1.4 秒呈现︰

JavaScript first

我获得镶边、 Firefox 和 Internet Explorer 中相似的结果。在 Opera 但是,排序只是并不重要。

什么信息出现时才会出现的 JavaScript 解释程序会拒绝开始下载所有 CSS 之前。因此,似乎,让 JavaScript 包括第一次为多个运行时 JavaScript 线程获取的效率更高。

我不够完整,是对建议之前 JavaScript 包括 CSS 位置包含不正确的?

很显然,我们无法添加异步或使用 setTimeout 来释放呈现线程或将 JavaScript 代码放在页脚中,或使用 JavaScript 加载程序。这里的要点是必不可少的 JavaScript 位和 CSS 位头中的排序有关。

2012-02-14 03:24:54
问题评论:

为 1511 vs 1422 统计上显著的差异?这就是 6%。平均人类值得一提的性能差异的一般阈值是大约 20%。

点是,重新排序,则清除此任意延迟,可以将延迟设置为任何需要的内容,它只是演示了该问题。

是您 100 毫秒的延迟?在您的屏幕抓图的区别是 89ms年。在您的 URL 是delay=400&amp;jsdelay=1000delay=500即远 100 毫秒或 89ms年。我想我很清楚指的数字。

"如果 Javascript 中包括第一次来,Javascript 引擎必须分析它所有然后再继续下一组资源。这意味着呈现线程无法完全显示该页,因为它不存在它所需要的所有样式。"-如果 JS 包括是头之前无论呈现页面时,将执行 JS CSS 是否包括了之前或之后。

不确定是否我考虑这一点,但加载时的感觉也是非常重要。因此,例如,如果加载 CSS 首先为您提供了甚至只是页面背景颜色/纹理,看起来会更快。绝对的加载时间可能不是这样的表现。

回答:

这是一个非常有趣的问题。我始终将放我的 CSS <link href="...">s 之前我 JS <script src="...">s 因为"我读一次,它是更好。"因此,您说的没错;现在是时候我们做一些实际的研究 !

我将我自己测试工具节点 (下面代码) 中设置。从根本上说,i:

  • 确保没有任何 HTTP 缓存,浏览器必须执行完整下载每次加载页时。
  • 为了模拟实际情况,我包括 jQuery 和H5BP CSS (因此没有了相当数量的脚本/CSS 来分析)
  • 设置两个页面的一个使用 CSS 前一个使用 CSS 后脚本的脚本。
  • 记录的时间为<head>外部脚本执行
  • 录制时间为<body>执行,这是类似于DOMReady内联脚本.
  • 延迟的 500年将 CSS 和/或脚本发送到浏览器。
  • 3 主要浏览器中运行测试 20 倍。

结果

首先,用 CSS 文件延迟 500年:

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 583ms  36ms  | 559ms  42ms  | 565ms 49ms
St Dev      | 15ms   12ms  | 9ms    7ms   | 13ms  6ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 584ms  521ms | 559ms  513ms | 565ms 519ms
St Dev      | 15ms   9ms   | 9ms    5ms   | 13ms  7ms

接下来,设置 jQuery 500 而不是 CSS 的延迟︰

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 597ms  556ms | 562ms  559ms | 564ms 564ms
St Dev      | 14ms   12ms  | 11ms   7ms   | 8ms   8ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 598ms  557ms | 563ms  560ms | 564ms 565ms
St Dev      | 14ms   12ms  | 10ms   7ms   | 8ms   8ms

最后,我设置jQuery 和 CSS 按 500年延迟︰

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 620ms  560ms | 577ms  577ms | 571ms 567ms
St Dev      | 16ms   11ms  | 19ms   9ms   | 9ms   10ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 623ms  561ms | 578ms  580ms | 571ms 568ms
St Dev      | 18ms   11ms  | 19ms   9ms   | 9ms   10ms

结论

首先,是一定要注意我所奉行,有脚本位于<head>文档 (而不是<body>的结尾) 的假设。有关于为什么您可以链接到您的脚本在<head>而不是文档的最终的各种参数,但这是此答案的范围之外。这是关于严格<script>s 是否应放在<head> <link>s 之前.

在现代的桌面浏览器,它看起来像链接到 CSS 第一个永远不会提供的性能改进。将 CSS 放后脚本获取您的增益 CSS 和脚本会延迟,但当延迟 CSS 可以大大改善。(显示在结果的第一组的last列)。

考虑到链接的 CSS 最后似乎不会造成损害性能,而且可以在某些情况下,您应链接到外部样式表之后您将链接到外部脚本只能在桌面浏览器上的收益如果提供的旧浏览器的性能不是关键因素。上读取的移动情况。

为什么?

从历史上看,当浏览器遇到<script>标记指向外部资源,浏览器将停止分析 HTML,检索脚本,执行它,然后继续分析 HTML。与此相反,如果浏览器遇到外部样式表<link> ,它将继续分析 HTML,它获取到 CSS 文件 (并行) 时。

因此,首先放入样式表广泛重复建议他们将第一次,下载并能并行加载的第一个脚本下载。

但是,当今的浏览器 (包括所有使用测试上面的浏览器) 实施了推理分析,其中浏览器"提前"在 HTML 看起来开始下载脚本下载并执行的资源。

在不进行推理分析的旧浏览器,放置脚本首先会影响性能因为他们将不会下载并行。

浏览器支持

推理分析中第一次实现: (以及所占全球桌面浏览器用户使用此版本或更高版本自 2012 年 1 月起)

  • 铬 (100%) 1 (易于 525 使用的功能)
  • IE 8 (75%)
  • Firefox 3.5 (96%)
  • Safari 4 (99%)
  • Opera 11.60 (85%)

总计,大约 85%的在使用桌面浏览器目前支持推理加载。将脚本放之前 CSS 将对性能产生负面影响对 15%的用户全局;YMMV 基于站点的特定访问群体。(和记忆数字收缩)。

移动浏览器上,它是有点难以获得权威数字正是由于异类移动浏览器和操作系统环境。在易于使用的功能 525 (2008 年 3 月 3 日发布),实现推理呈现和几乎每一个物有所值的移动浏览器基于易于使用的功能,我们可以得出结论,因为"大多数"移动浏览器应该支持它。根据quirksmode,iOS 2.2/Android 1.0 使用易于使用的功能 525。我也不知道 Windows Phone 如下所示。

但是,我在我的 Android 4 设备上运行测试和我所看到的类似于桌面搜索结果的数字,而我极好新远程调试器中铬的 Android,进行挂钩和网络选项卡表明浏览器实际上正在等待下载 CSS JavaScripts 完全加载 – 换句话说,直到甚至最新版 Android 易于使用的功能似乎不支持推理分析。我怀疑它可能会关闭 CPU,内存,和/或网络限制由于固有的移动设备。

代码

别怪 sloppiness – 这是问答 d。

app.js

var express = require('express')
, app = express.createServer()
, fs = require('fs');

app.listen(90);

var file={};
fs.readdirSync('.').forEach(function(f) {
    console.log(f)
    file[f] = fs.readFileSync(f);
    if (f != 'jquery.js' && f != 'style.css') app.get('/' + f, function(req,res) {
        res.contentType(f);
        res.send(file[f]);
    });
});


app.get('/jquery.js', function(req,res) {
    setTimeout(function() {
        res.contentType('text/javascript');
        res.send(file['jquery.js']);
    }, 500);
});

app.get('/style.css', function(req,res) {
    setTimeout(function() {
        res.contentType('text/css');
        res.send(file['style.css']);
    }, 500);
});


var headresults={
    css: [],
    js: []
}, bodyresults={
    css: [],
    js: []
}
app.post('/result/:type/:time/:exec', function(req,res) {
    headresults[req.params.type].push(parseInt(req.params.time, 10));
    bodyresults[req.params.type].push(parseInt(req.params.exec, 10));
    res.end();
});

app.get('/result/:type', function(req,res) {
    var o = '';
    headresults[req.params.type].forEach(function(i) {
        o+='
' + i;
    });
    o+='
';
    bodyresults[req.params.type].forEach(function(i) {
        o+='
' + i;
    });
    res.send(o);
});

css.html

<!DOCTYPE html>
<html>
    <head>
        <title>CSS first</title>
        <script>var start = Date.now();</script>
        <link rel="stylesheet" href="style.css">
        <script src="jquery.js"></script>
        <script src="test.js"></script>
    </head>
    <body>
        <script>document.write(jsload - start);bodyexec=Date.now()</script>
    </body>
</html>

js.html

<!DOCTYPE html>
<html>
    <head>
        <title>CSS first</title>
        <script>var start = Date.now();</script>
        <script src="jquery.js"></script>
        <script src="test.js"></script>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <script>document.write(jsload - start);bodyexec=Date.now()</script>
    </body>
</html>

test.js

var jsload = Date.now();


$(function() {
    $.post('/result' + location.pathname.replace('.html','') + '/' + (jsload - start) + '/' + (bodyexec - start));
});

jquery.js 是jquery 1.7.1.min.js

这是一个极好的回答,感谢使用科学 !"在现代浏览器,看起来永远不会首先将链接到 CSS 提供的性能改进"您结果,我认为试题标题的答案是,CSS 的旧建议首先是显然无效。

我等不及的那一天,我只需要支持现代浏览器 !我是-如果这是情形 !

@scunlife︰ 有一点我们必须停止有人愿意迎合。我并不说我们应该破坏站点时遇到即 6,但我们不应作出任何努力优化即 6 体验。我测试了︰ 也即 8 + 中,FF 8+ Chrome 工作吗?很好。它是否允许 Lynx 中要完成的作业?还行。

今天 @scunliffe 现代明天将会是陈旧。请记住 IE6 其时间,被认为是革命性的浏览器和自然这样一把。

@scunliffe 记住全部关闭此讨论是关于尝试做出最佳的较差的情况下,显然在理想的世界中所有 javascript 是异步加载或完全呈现页之后

有两个主要原因使之前 JavaScript 的 CSS。

  1. 当他们开始下载脚本,旧浏览器 (Internet Explorer 6-7,Firefox 2 等) 将阻止所有后续下载。因此按顺序获取下载如果有跟b.css a.js ︰ 第一个 b。如果您有跟a.js b.css获取下载这些并行以便更快地加载网页。

  2. 直到所有的样式表将下载-这是在所有浏览器中呈现任何内容。不同脚本-它们阻止所有脚本标记下面的页中的 DOM 元素的呈现。如果您将您的脚本放在头部则意味着整个页面阻止呈现下载所有的样式表和所有脚本前。时就应该阻止所有呈现为样式表 (使您获得正确的样式设置第一个时间,并避免和样式的内容 FOUC 闪光灯),它没有任何意义,阻止呈现整个页面的脚本。通常为脚本并不影响任何 DOM 元素或 DOM 元素的一部分。最好加载为低在尽可能的情况下,页面中的脚本或更好的是异步加载。

它的乐趣,使用Cuzillion创建的示例。例如,此页具有脚本头因此整页是空白的直到它已完成下载。但是,如果我们将脚本移到正文块结尾页标题呈现因为那些 DOM 元素发生上面的脚本标记,您可以在此页上看到.

承兑的 Steve 失望的答案,但我将添加到他所提到的相关文章︰ stevesouders.com/blog/2009/04/27/...

看到哪个浏览器都支持async属性,其时他说:"更好的是这些异步加载"— 斯蒂夫正在这里推荐stackoverflow.com/questions/1834077/...

您好您能告诉我为什么任何人都可以链接@import指令的 CSS 文件?

什么是 2 的来源),如果为 true,您能然后页面完成加载内容,则 CSS 是解释为什么有时稍后应用一两秒?(此情况,很少,我自己 < 头 > 标记中的 CSS 所在的页面上)

所以我们应该将jQuery + jQuery UI + 页的末尾$(document).ready(function () { });始终将它按预期方式工作?

我不会强调太多的结果,有了,我认为是主观的但我有其他的原因来解释您最好放在 CSS,js 之前。

在您的网站的加载,期间有两种情况下,您会看到︰

案例 1︰ 白色屏幕 > 和样式的网站 > 样式网站 > 交互 > 样式和交互式网站

案例 2︰ 白色屏幕 > 和样式的网站 > 交互 > 样式网站 > 样式和交互式网站


我真诚地不能想象任何人选择列的第 2。这意味着在使用低速 internet 连接的访问者,将面对和样式的网站,允许他们使用 Javascript (因为它已经加载) 与其进行交互。此外,要花费一段时间看和样式的网站将被最大化这种方式。为什么会有人想的?

也可用于更好地为jQuery 状态

"当使用依赖于 CSS 样式属性的值的脚本时,务必要引用外部样式表或引用脚本之前嵌入样式元素"。

当按错误的顺序加载的文件 (第一个 JS,然后 CSS),任何 Javascript 代码依赖于 CSS 文件中设置的属性 (例如宽度或高度的 div) 将不会加载正确。似乎,与错误的加载顺序,正确的属性有时已知的 Javascript (也许这因为竞态条件?)。这种影响似乎更大或更小,这取决于使用的浏览器。

您将如何保证所有 javascript 执行之前加载 css 有关?你能吗?或者您 javascript 应不足以处理这种情况,其中样式可能不一定会加载。

在您的个人计算机或 web 服务器上执行您的测试?它是一个空白页,还是复杂的联机系统,与图像、 数据库,等等。?您的脚本执行的简单悬停事件的操作,或者他们是否为您的网站呈现的方式,与用户交互的核心组件?有几种方法,可以考虑在这里和这些建议几乎总是成为规则的匹配性冒险高人才 web 开发。

"将样式表的顶部和底部的脚本"规则的目的是,一般情况下,它是最佳的方法,以实现最佳的渐进式呈现这是用户体验的关键。

所有其它备用︰ 假设您的测试是有效的并且确实产生结果与常用的规则,它将感到不奇怪,真的。每一个网站 (和使整个出现在用户的屏幕上所需的所有内容) 不同,互联网不断在发展。

我喜欢做点以粗体显示,但是操作都在谈论不同的顺序与这两个顶部,底部也不会发生什么情况。

因此,"假设 [他] 测试是有效的。"

包括 CSS 文件之前 Javascript 出于不同的原因。

如果我 Javascript 需要进行动态调整的某些网页元素 (适用于 CSS 实际上是在后面主这些极端情况下),然后加载 CSS,JS russing 后可能会导致争用问题,其中元素应用 CSS 样式之前调整其大小,因此看起来很怪异时最后进入样式。如果我预先加载 CSS 我可以保证按预期顺序执行各项任务,最终布局是我希望它是。

在一些浏览器上,这将中断一天。我不猜。

jcolebrand︰ 是的我认为我没有 drunk 足够的咖啡,当我写了这。(现在想来,我想重要的事情都只是为了避免动态加载的 CSS 和放 JS domReady 事件内的,如果需要进行动态调整大小)

脚本应该不应更改任何显示。这就是 CSS 作业。HTML 内容,CSS = = 动态内容,javascript 更改内容的显示方式。Js 应该只行为还后 (或同时) DOMContentLoaded 激发一些小但非常特殊的情况。

@brunoais︰ 某些布局只能创建使用 Javascript 不过。例如,必须通过 Javascript 进行动态调整所需要的任何东西,(好像是 100%-20px 的大小) 的一些事项需要进行移植在旧浏览器的 Javascript。

在这些情况下,@missingno 只需使用 DOMContentLoaded 事件,无论如何。但我明白您的意思。(愚蠢的 IE) !

请输入您的翻译

Is the recommendation to include CSS before JavaScript invalid?

确认取消