En innumerables lugares en línea, he visto la recomendación de incluir CSS antes de JavaScript. El razonamiento es generalmente de esta forma :
Cuando se trata de ordenar su CSS y JavaScript, desea que su CSS sea lo primero. La razón es que el hilo de renderizado tiene toda la información de estilo que necesita para renderizar la página. Si el JavaScript incluye primero, el motor de JavaScript debe analizarlo todo antes de continuar con el siguiente conjunto de recursos. Esto significa que el hilo de renderizado no puede mostrar completamente la página, ya que no tiene todos los estilos que necesita.
Mi prueba real revela algo bastante diferente:
Mi arnés de prueba
Utilizo el siguiente script de Ruby para generar demoras específicas para varios recursos:
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..."
}
El mini servidor anterior me permite establecer retrasos arbitrarios para archivos JavaScript (tanto del servidor como del cliente) y retrasos arbitrarios de CSS. Por ejemplo,http://10.0.0.50:8081/test.css?delay=500
me da un retraso de 500 ms para transferir el CSS.
Yo uso la siguiente página para probar.
<!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>
Cuando incluyo el CSS primero, la página tarda 1,5 segundos en renderizarse:
Cuando incluyo el JavaScript primero, la página tarda 1,4 segundos en renderizarse:
Obtengo resultados similares en Chrome, Firefox e Internet Explorer. En Opera, sin embargo, el orden simplemente no importa.
Lo que parece estar sucediendo es que el intérprete de JavaScript se niega a comenzar hasta que se descargue todo el CSS. Entonces, parece que tener JavaScript incluido primero es más eficiente ya que el hilo de JavaScript obtiene más tiempo de ejecución.
Me falta algo, ¿la recomendación de colocar CSS incluye antes de JavaScript no es correcta?
Está claro que podríamos agregar asíncrono o usar setTimeout para liberar el hilo de renderizado o poner el código JavaScript en el pie de página, o usar un cargador de JavaScript. El punto aquí es sobre el pedido de bits esenciales de JavaScript y bits CSS en la cabeza.
delay=400&jsdelay=1000
y delay=500
que no está cerca de 100 ms o 89 ms. Supongo que no tengo claro a qué números te refieres.