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

  显示原文与译文双语对照的内容

在网上无数的地方我看到了在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

在 Chrome,Firefox 和 IE 中得到相似的结果。 然而,在 Opera 中,排序并不重要。

似乎发生的是JavaScript解释器拒绝启动,直到所有的CSS都被下载。 因此,当JavaScript线程获得更多的运行时间时,JavaScript包含第一个更高效。

我丢失了一些东西,推荐放置CSS的建议包括在JavaScript包含不正确之前?

很明显,我们可以添加async或者使用setTimeout释放渲染线程,或者将JavaScript代码放在页脚中,或者使用JavaScript加载器。 这里的要点是在head中排列基本的JavaScript位和CSS位。

时间:

在JavaScript之前放置CSS有两个主要原因。

  1. 旧浏览器( IE 6 -7,Firefox 2,等等 ) 在下载脚本时将阻止所有后续下载。 如果你有 a.js 后跟 b.css,它们会按顺序下载: 然后并行谓语页面加载更quickly,前一个b 。如果你有 b.css 后跟 a.js 他们得到 downloaded.

  2. 在所有的样式表下载之前都不会呈现任何内容- 在所有浏览器中都是这样。 在下面的是不同的- 他们阻塞渲染的所有DOM元素,这些元素 page,脚本该脚本标记. 如果你将脚本放在头部,那么就意味着整个页面都被阻止,直到所有样式表和所有脚本都被下载。 尽管阻止样式表的所有呈现都是有意义的,但是对于脚本块的渲染没有意义。 脚本通常不会影响任何DOM元素或者DOM元素的一部分。 最好在页面中尽可能低的加载脚本,或者更好地加载它们。

使用 Cuzillion编辑器创建示例很有趣。 例如这个页面在HEAD中有一个脚本,所以整个页面都是空白的,直到完成下载。 但在, 这里页面上,如果我们将该脚本的末尾身体块上方的页标题呈现因为那些DOM元素都呈现脚本标记,如你可以看看。

建议在JavaScript之前包含CSS文件,原因如下:

JavaScript阻止浏览器做任何事情,直到它被下载,解析和执行。 为什么因为JavaScript文件可能包含诸如 document.write("<--") 这样的指令,当执行时,更改页面的标记。!

如果把CSS文件放在HTML源文件中的JavaScript文件之前,事情会变得更好。 浏览器可以并行加载两个文件( CSS和 JavaScript ) 。 当然它会在试图下载,解析和执行JavaScript文件时阻塞,但是这个周期将被用来并行下载其他文件。

...