В бесчисленных местах онлайн я видел рекомендацию включать CSS до JavaScript. Обоснование обычно этой формы:
Когда дело доходит до заказа CSS и JavaScript, вы хотите, чтобы ваш CSS прийти первым. Причина в том, что поток рендеринга имеет все которая должна отображать страницу. Если JavaScript включает, прежде всего, движок JavaScript должен разбирать все это до переходя к следующему набору ресурсов. Это означает, что рендеринг нить не может полностью показать страницу, так как она не имеет всех стилей, в которых он нуждается.
Мое фактическое тестирование показывает что-то совсем другое:
Мой тестовый жгут
Я использую следующий Ruby script для генерации определенных задержек для различных ресурсов:
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="#" onclick="location.href='http://10.0.0.50:8081/test.css?delay=500'; return false;" type="text/css" rel="stylesheet">
      <script type="text/javascript" src="http://10.0.0.50:8081/test2.js?delay=400&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 и Internet Explorer. В Opera, однако, порядок просто не имеет значения.
Что, по-видимому, происходит, так это то, что интерпретатор JavaScript отказывается запускать, пока не будет загружен весь CSS. Таким образом, кажется, что включение JavaScript в первую очередь более эффективно, так как поток JavaScript получает больше времени выполнения.
Мне что-то не хватает, рекомендуется ли размещать CSS-код до того, как JavaScript включится неверно?
Ясно, что мы могли бы добавить async или использовать setTimeout, чтобы освободить поток рендеринга или поместить код JavaScript в нижний колонтитул или использовать загрузчик JavaScript. Здесь речь идет о упорядочении существенных битов JavaScript и бит CSS в голове.


