В бесчисленных местах онлайн я видел рекомендацию включить CSS до JavaScript. Рассуждения, как правило, имеют следующую форму :
Когда дело доходит до заказа вашего 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&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-включений?
Понятно, что мы могли бы добавить асинхронность или использовать setTimeout, чтобы освободить поток рендеринга, или поместить код JavaScript в нижний колонтитул, или использовать загрузчик JavaScript. Суть здесь в том, чтобы упорядочить основные биты JavaScript и биты CSS в голове.
delay=400&jsdelay=1000
и delay=500
это далеко не 100 мс или 89 мс. Думаю, мне неясно, на какие цифры вы ссылаетесь.