在网上无数的地方,我都看到过在JavaScript之前使用CSS的建议。推理一般是这样的:

当涉及到CSS和JavaScript的排序时,你需要你的CSS 先来。原因是呈现线程拥有所有的 样式显示页面所需的信息。如果JavaScript include首先出现,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秒来呈现:

当我首先包含JavaScript时,页面需要1.4秒来呈现:

我在Chrome、Firefox和ie浏览器上得到了类似的结果。然而,在Opera中,顺序并不重要。

似乎发生的情况是,JavaScript解释器在下载所有CSS之前拒绝启动。因此,首先使用JavaScript包含似乎更有效,因为JavaScript线程获得了更多的运行时间。

我遗漏了什么吗?把CSS include放在JavaScript include之前的建议是不正确的吗?

显然,我们可以添加async或使用setTimeout来释放呈现线程,或将JavaScript代码放在页脚中,或使用JavaScript加载器。这里的重点是关于基本JavaScript位和CSS位在头部的排序。


当前回答

我们必须记住,新的浏览器已经在它们的JavaScript引擎、解析器等方面进行了优化,优化了常见的代码和标记问题,而在Internet Explorer 8或之前的老式浏览器中遇到的问题已经不再相关,不仅涉及标记,还涉及JavaScript变量、元素选择器等的使用。

我可以预见在不久的将来,技术发展到一定程度,性能就不再是问题了。

其他回答

我们必须记住,新的浏览器已经在它们的JavaScript引擎、解析器等方面进行了优化,优化了常见的代码和标记问题,而在Internet Explorer 8或之前的老式浏览器中遇到的问题已经不再相关,不仅涉及标记,还涉及JavaScript变量、元素选择器等的使用。

我可以预见在不久的将来,技术发展到一定程度,性能就不再是问题了。

我认为这并不适用于所有情况。因为CSS内容可以并行下载,但JavaScript代码不能。考虑相同的情况:

与其只有一段CSS内容,不如拿出两三个CSS文件,然后试试这些方法,

CSS . . CSS . . JavaScript CSS . . JavaScript . . CSS JavaScript . . CSS . . CSS

我确定CSS..CSS..JavaScript会给出比其他方法更好的结果。

出于不同的原因,我在JavaScript之前包含了CSS文件。

如果我的JavaScript代码需要做一些页面元素的动态大小(对于那些角落的情况下,CSS是真正的主要在后面),然后在JS是russing后加载CSS可能会导致竞争条件,其中元素是在CSS样式应用之前调整大小,因此,当样式最终启动时看起来很奇怪。如果我提前加载CSS,我可以保证事情按照预期的顺序运行,最终的布局是我想要的。

2020年的答案是:这可能并不重要

这里最好的答案来自2012年,所以我决定自己测试一下。在Chrome for Android上,JS和CSS资源是并行下载的,我无法检测到页面渲染速度的差异。

我在博客上写了一篇更详细的文章

我不太确定你是如何使用JavaScript测试“渲染”时间的。然而,考虑到这一点:

One page on your site is 50 kB which is not unreasonable. The user is on the East Coast while your server is on the west. MTU is definitely not 10k so there will be a few trips back and forth. It may take 1/2 a second to receive your page and style sheets. Typically (for me) JavaScript (via jQuery plugin and such) are much more than CSS. There’s also what happens when your Internet connection chokes up midway on the page, but let’s ignore that (it happens to me occasionally and I believe the CSS renders, but I am not 100% sure).

由于CSS在头部,可能会有额外的连接来获取它,这意味着它可能会在页面完成之前完成。无论如何,在输入页面的其余部分和JavaScript文件(更多字节)时,页面是无样式的,这使得站点/连接看起来很慢。

即使JavaScript解释器在CSS完成之前拒绝启动,下载JavaScript代码所花费的时间,特别是在远离服务器时,也会减少CSS的时间,这将使网站看起来不漂亮。

这是一个小的优化,但这就是它的原因。