Di banyak tempat online saya telah melihat rekomendasi untuk memasukkan CSS sebelum JavaScript. Alasannya secara umum, dari bentuk ini :
Ketika datang untuk memesan CSS dan JavaScript Anda, Anda ingin CSS Anda yang lebih dulu. Alasannya adalah bahwa thread rendering memiliki semua informasi gaya yang diperlukan untuk membuat halaman. Jika JavaScript termasuk yang diutamakan, mesin JavaScript harus menguraikan semuanya sebelum melanjutkan ke rangkaian sumber daya berikutnya. Ini berarti untaian rendering tidak dapat sepenuhnya menampilkan halaman, karena tidak memiliki semua gaya yang dibutuhkan.
Pengujian saya yang sebenarnya mengungkapkan sesuatu yang sangat berbeda:
Uji harness saya
Saya menggunakan skrip Ruby berikut untuk menghasilkan penundaan spesifik untuk berbagai sumber daya:
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..."
}
Server mini di atas memungkinkan saya untuk mengatur penundaan sewenang-wenang untuk file JavaScript (baik server dan klien) dan penundaan CSS sewenang-wenang. Misalnya, http://10.0.0.50:8081/test.css?delay=500
beri saya penundaan 500 ms saat mentransfer CSS.
Saya menggunakan halaman berikut untuk menguji.
<!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>
Ketika saya memasukkan CSS terlebih dahulu, halaman membutuhkan 1,5 detik untuk merender:
Ketika saya memasukkan JavaScript terlebih dahulu, halaman membutuhkan 1,4 detik untuk merender:
Saya mendapatkan hasil yang serupa di Chrome, Firefox dan Internet Explorer. Namun di Opera, pemesanan tidak masalah.
Apa yang tampaknya terjadi adalah bahwa penerjemah JavaScript menolak untuk memulai sampai semua CSS diunduh. Jadi, tampaknya memiliki JavaScript yang disertakan terlebih dahulu lebih efisien karena utas JavaScript semakin lama berjalan.
Apakah saya kehilangan sesuatu, apakah rekomendasi untuk memasukkan CSS sebelum JavaScript termasuk tidak benar?
Jelas bahwa kita dapat menambahkan async atau menggunakan setTimeout untuk membebaskan utas render atau meletakkan kode JavaScript di footer, atau menggunakan loader JavaScript. Intinya di sini adalah tentang pemesanan bit JavaScript penting dan bit CSS di kepala.
delay=400&jsdelay=1000
dan delay=500
yang mana dekat 100ms atau 89ms. Saya kira saya tidak jelas nomor mana yang Anda maksud.