建议在JavaScript无效之前包含CSS吗?

我们两清 提交于 2020-04-18 11:33:47

问题:

In countless places online I have seen the recommendation to include CSS prior to JavaScript. 在网上无数的地方,我已经看到了在JavaScript之前包含CSS的建议。 The reasoning is generally, of this form : 一般来说,推理的形式如下:

When it comes to ordering your CSS and JavaScript, you want your CSS to come first. 在订购CSS和JavaScript时,您希望首先使用CSS。 The reason is that the rendering thread has all the style information it needs to render the page. 原因是渲染线程具有渲染页面所需的所有样式信息。 If the JavaScript includes come first, the JavaScript engine has to parse it all before continuing on to the next set of resources. 如果首先包含JavaScript,则JavaScript引擎必须先解析它,然后再继续使用下一组资源。 This means the rendering thread can't completely show the page, since it doesn't have all the styles it needs. 这意味着渲染线程无法完全显示页面,因为它没有所需的所有样式。

My actual testing reveals something quite different: 我的实际测试揭示了一些截然不同

My test harness 我的测试工具

I use the following Ruby script to generate specific delays for various resources: 我使用以下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..."
}

The above mini server allows me to set arbitrary delays for JavaScript files (both server and client) and arbitrary CSS delays. 上面的迷你服务器允许我为JavaScript文件(服务器和客户端)和任意CSS延迟设置任意延迟。 For example, http://10.0.0.50:8081/test.css?delay=500 gives me a 500 ms delay transferring the CSS. 例如, http://10.0.0.50:8081/test.css?delay=500 delay = 500给我一个500毫秒的延迟传输CSS。

I use the following page to test. 我使用以下页面进行测试。

<!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>

When I include the CSS first, the page takes 1.5 seconds to render: 当我首先包含CSS时,页面需要1.5秒才能呈现:

CSS首先

When I include the JavaScript first, the page takes 1.4 seconds to render: 当我首先包含JavaScript时,该页面需要1.4秒才能呈现:

首先是JavaScript

I get similar results in Chrome, Firefox and Internet Explorer. 我在Chrome,Firefox和Internet Explorer中获得了类似的结果。 In Opera however, the ordering simply does not matter. 然而,在Opera中,排序无关紧要。

What appears to be happening is that the JavaScript interpreter refuses to start until all the CSS is downloaded. 似乎正在发生的事情是JavaScript解释器在下载所有CSS之前拒绝启动。 So, it seems that having JavaScript includes first is more efficient as the JavaScript thread gets more run time. 因此,似乎首先使用JavaScript包含更高效,因为JavaScript线程会获得更多的运行时间。

Am I missing something, is the recommendation to place CSS includes prior to JavaScript includes not correct? 我错过了什么,建议将CSS包含在JavaScript之前包括不正确吗?

It is clear that we could add async or use setTimeout to free up the render thread or put the JavaScript code in the footer, or use a JavaScript loader. 很明显,我们可以添加async或使用setTimeout来释放渲染线程或将JavaScript代码放在页脚中,或者使用JavaScript加载器。 The point here is about ordering of essential JavaScript bits and CSS bits in the head. 这里的要点是关于头部中基本JavaScript位和CSS位的排序。


解决方案:

参考一: https://stackoom.com/question/ctsi/建议在JavaScript无效之前包含CSS吗
参考二: https://oldbug.net/q/ctsi/Is-the-recommendation-to-include-CSS-before-JavaScript-invalid
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!