An unzähligen Stellen im Internet habe ich die Empfehlung gesehen, CSS vor JavaScript einzubinden. Die Argumentation ist im Allgemeinen, in dieser Form :
Wenn es darum geht, Ihr CSS und JavaScript zu ordnen, sollten Sie Ihr CSS an erster Stelle stehen. Der Grund dafür ist, dass der Rendering-Thread über alle Stilinformationen hat, die er zum Rendern der Seite benötigt. Wenn die JavaScript zuerst kommt, muss die JavaScript-Engine alles parsen, bevor sie bevor sie mit der nächsten Gruppe von Ressourcen fortfährt. Das bedeutet, dass der Rendering Thread kann die Seite nicht vollständig anzeigen, da er nicht über alle Stile, die er benötigt.
Mein aktueller Test zeigt etwas ganz anderes:
Mein Test-Kabelbaum
Ich verwende Folgendes Rubinrot Skript, um spezifische Verzögerungen für verschiedene Ressourcen zu erzeugen:
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..."
}
Der obige Miniserver erlaubt es mir, beliebige Verzögerungen für JavaScript-Dateien (sowohl Server als auch Client) und beliebige CSS-Verzögerungen einzustellen. Zum Beispiel, http://10.0.0.50:8081/test.css?delay=500
gibt mir eine Verzögerung von 500 ms bei der Übertragung des CSS.
Ich verwende die folgende Seite zum Testen.
<!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>
Wenn ich das CSS zuerst einfüge, braucht die Seite 1,5 Sekunden zum Rendern:
Wenn ich das JavaScript zuerst einfüge, braucht die Seite 1,4 Sekunden zum Rendern:
Ich erhalte ähnliche Ergebnisse in Chrome, Firefox und Internet Explorer. Unter Oper Die Reihenfolge spielt jedoch keine Rolle.
Es scheint so zu sein, dass der JavaScript-Interpreter sich weigert zu starten, bis alle CSS heruntergeladen sind. Es scheint also, dass es effizienter ist, JavaScript zuerst einzubinden, da der JavaScript-Thread mehr Laufzeit erhält.
Habe ich etwas verpasst? Ist die Empfehlung, CSS-Includes vor JavaScript-Includes zu platzieren, nicht korrekt?
Es ist klar, dass wir async hinzufügen oder setTimeout verwenden könnten, um den Render-Thread freizugeben, oder den JavaScript-Code in die Fußzeile stellen oder einen JavaScript-Loader verwenden könnten. Hier geht es um die Anordnung der wesentlichen JavaScript- und CSS-Bits im Kopf.