CSS önce eklemek önerisi JavaScript geçersiz mi?
Sayısız online JavaScript CSS önce dahil etmek için öneri gördüm. Mantık genel olarak, 33**:
CSS ve JavaScript sipariş geldiğinde, CSS istiyorum birinci gelmek. Bu nedenle işleme iş parçacığı tüm olmasıdır stil bilgileri sayfası oluşturmak gerekiyor. JavaScript ise içerir ilk gelen JavaScript motoru, daha önce ayrıştırmak için vardır kaynakların bir sonraki sete devam ediyoruz. Bu işleme anlamına gelir iplik tüm önemi yok, çünkü tamamen sayfası gösterebilir. ihtiyacı stilleri.
Benim gerçek test oldukça farklı bir şey ortaya çıkarır:
Benim test koÅŸum
Aşağıdaki Ruby komut dosyası, çeşitli kaynaklar için belirli gecikmeler oluşturmak için kullanın:
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..."
}
Yukarıda mini server dosyaları (server ve client) ve keyfi CSS JavaScript gecikmeler için rasgele bir gecikme ayarlamanızı sağlar. Örneğin, http://10.0.0.50:8081/test.css?delay=500
bana 500 ms verir CSS aktarma gecikme.
Aşağıdaki sayfayı test etmek için kullanın.
<!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 ilk ben dahil, bir sayfası 1,5 saniye işlemek için alır:
JavaScript ilk olarak ben dahil, sayfa 1.4 saniye işlemek için alır:
Chrome, Firefox ve Internet Explorer için de benzer sonuçlar alıyorum. Opera ancak, sipariş sadece önemli değil.
Oluyor gibi görünüyor ne JavaScript yorumlayıcı CSS yüklenir kadar başlatmak için reddediyor. Bu yüzden, sahip JavaScript içerir ilk JavaScript iş parçacığı daha fazla çalışma zamanı geldikçe daha etkili gibi görünüyor.
Eksik bir şey, bir yer için öneri CSS içerir JavaScript önce yanlış mıyım?
CEVAP
Bu çok ilginç bir soru. Her zaman benim CSS "daha iyi olduğunu bir kez okudum." çünkü benim JS önce <link href="...">
<script src="...">
s koydum Yani, haklısın, ciddi bir araştırma yapıyoruz tam zamanı!
Yukarı Düğüm (kod aşağıda) kendi test koşum takımı kurdum. Temelde, Ben De:
- Tarayıcı tam indir her zaman yapmak zorunda diye HTTP önbellekleme vardı emin yapılmış bir sayfa yüklenir.
- Gerçeklik simülasyonu, DV ve H5BP CSS script/CSS yeterli miktarda ayrıştırılamadı () ben dahil
- İki sayfa önce script - CSS ile bir komut dosyası sonra CSS ile ayarlamak.
- Dış komut için ne kadar sürdüğünü kaydetti
<head>
yürütmek için - Bu satır içi komut dosyası için ne kadar sürdüğünü kaydetti
<body>
DOMReady
benzer olan yürütmek için. - Gecikmeli 500ms tarafından tarayıcıya CSS ve/veya komut göndermek.
- 3 büyük tarayıcılarda test 20 kez koştu.
Sonuçları
İlk olarak, CSS dosyası 500ms gecikme ile
Browser: Chrome 18 | IE 9 | Firefox 9
CSS: first last | first last | first last
=======================================================
Header Exec | | |
Average | 583ms 36ms | 559ms 42ms | 565ms 49ms
St Dev | 15ms 12ms | 9ms 7ms | 13ms 6ms
------------|--------------|--------------|------------
Body Exec | | |
Average | 584ms 521ms | 559ms 513ms | 565ms 519ms
St Dev | 15ms 9ms | 9ms 5ms | 13ms 7ms
Bir sonraki dil eklentisi CSS yerine 500ms tarafından gecikme ayarlayın:
Browser: Chrome 18 | IE 9 | Firefox 9
CSS: first last | first last | first last
=======================================================
Header Exec | | |
Average | 597ms 556ms | 562ms 559ms | 564ms 564ms
St Dev | 14ms 12ms | 11ms 7ms | 8ms 8ms
------------|--------------|--------------|------------
Body Exec | | |
Average | 598ms 557ms | 563ms 560ms | 564ms 565ms
St Dev | 14ms 12ms | 10ms 7ms | 8ms 8ms
Son olarak belirledimher ikisi de500ms tarafından gecikme için jQuery ve CSS:
Browser: Chrome 18 | IE 9 | Firefox 9
CSS: first last | first last | first last
=======================================================
Header Exec | | |
Average | 620ms 560ms | 577ms 577ms | 571ms 567ms
St Dev | 16ms 11ms | 19ms 9ms | 9ms 10ms
------------|--------------|--------------|------------
Body Exec | | |
Average | 623ms 561ms | 578ms 580ms | 571ms 568ms
St Dev | 18ms 11ms | 19ms 9ms | 9ms 10ms
Sonuç
İlk olarak, önemli karakterler mevcut belge <body>
sonu (karşıt olarak) <head>
yer olduğunu varsayarak hareket ediyorum unutmayın. Belgenin sonuna karşı <head>
komut bağlantı olabilir neden ile ilgili çeşitli tartışmalar vardır, ama bu cevap kapsamı dışındadır. Bu <script>
<head>
<link>
s önce gitmeli konusunda kesinlikle.
Modern MASAÜSTÜ tarayıcılar,ilk CSS bağlantı gibi görünüyoraslabir performans kazancı sağlar. Script sonra CSS koyarak hem CSS ve script geciktiğinde kazanmak önemsiz bir miktar alır, ama CSS gecikmeli size büyük kazanç sağlar. (Sonuçları ilk sette. last
sütun ile gösterilen)
Son CSS bağlama performansı zarar vermiyor amaolabilirbelirli koşullar altında kazanç sağlamakharici stil sayfaları bağlamak gerekirsonraharici komut dosyaları, bağlantımasaüstü tarayıcılar sadeceeski tarayıcıların performansını bir endişe değil.Cep telefonu durum için okumaya devam edin.
Neden?
Bir tarayıcı <script>
bir etiket bir dış kaynak gösteren karşılaşıldığında tarihsel olarak, tarayıcıdurHTML ayrıştırma, komut almak, çalıştırmak, HTML ayrıştırma devam edin. Eğer tarayıcı <link>
harici bir stil ile karşılaştı aksine, olacakdevambunu yaparken HTML ayrıştırma getirilen CSS dosyası (paralel olarak).
Bu nedenle, yaygın olarak tekrarlanan stil ilk koymak için tavsiyeler-ilk yükleme ve indirme için ilk komut paralel olarak yüklenmiş olabilir.
Ancak, modern tarayıcılar (yukarıdaki ile test ettim tarayıcıları dahil) tarayıcı "" HTML başlar ve indirme kaynakları . önde görünüyor speculative parsing, hayata geçirdik ^em>öncekomut dosyaları indirmek ve çalıştırmak.
Spekülatif ayrıştırma olmadan eski tarayıcılarda, ilk komut koyarak paralel indirme vermezler beri performansını etkileyecek.
Tarayıcı Desteği
Spekülatif ayrıştırma ilk uygulanan oldu: (dünya çapında masaüstü tarayıcı kullanıcıları bu sürümü kullanarak yüzdesi ya da Ocak 2012 kadar büyük ile birlikte)
- Krom 1 (Y 525) (100%)
- IE 8 (75%)
- Firefox 3.5 (96%)
- Safari 4 (99%)
- Opera 11.60 (85%)
Toplamda, yaklaşık kullanımda olan masaüstü tarayıcılar …'i spekülatif yükleme desteÄŸi. CSS önce koyarak komut kullanıcıların üzerinde bir performans ceza vargenel olarak; Sitenize özel kitleye göre YMMV. (Ve bu sayı düşüyor unutmayın.)
Mobil tarayıcılar, biraz daha basitçe nasıl heterojen Mobil Tarayıcı ve OS manzara nedeniyle kesin sayılar elde etmek. Spekülatif işleme Y 525 uygulanmıştır (Mar 2008 serbest), ve hemen hemen her değerli mobil web tarayıcı piyasaya sürdü olduğundan, "en" mobil tarayıcılar . sonucuna varabiliriz ^em>gerekirdestek. quirksmode, 2.2 iOS/Android 1.0 göre kullanmak Y 525. Telefonun neye benzediğini hiç bir fikrim yok.
AncakKoştum testte benim Android 4 Cihaz ve yaparken gördüm numaraları benzer masaüstü sonuçlar, bağladım o kadar fantastik yeni remote debugger Krom Android için, ve Ağ sekmesini gösterdi tarayıcı oldu aslında bekleyen indirme CSS kadar Javascript tamamen dolu-diğer bir deyişle,hatta Android için Y en yeni versiyonu spekülatif ayrıştırma desteği görünmüyor.CPU, bellek ve/veya ağ kısıtlamaları mobil cihazlar için doğası nedeniyle kapalı olabileceğinden şüpheleniyorum.
Kod
Bu ıslaklık affet-bu S&D oldu
app.js
var express = require('express')
, app = express.createServer()
, fs = require('fs');
app.listen(90);
var file={};
fs.readdirSync('.').forEach(function(f) {
console.log(f)
file[f] = fs.readFileSync(f);
if (f != 'jquery.js' && f != 'style.css') app.get('/' f, function(req,res) {
res.contentType(f);
res.send(file[f]);
});
});
app.get('/jquery.js', function(req,res) {
setTimeout(function() {
res.contentType('text/javascript');
res.send(file['jquery.js']);
}, 500);
});
app.get('/style.css', function(req,res) {
setTimeout(function() {
res.contentType('text/css');
res.send(file['style.css']);
}, 500);
});
var headresults={
css: [],
js: []
}, bodyresults={
css: [],
js: []
}
app.post('/result/:type/:time/:exec', function(req,res) {
headresults[req.params.type].push(parseInt(req.params.time, 10));
bodyresults[req.params.type].push(parseInt(req.params.exec, 10));
res.end();
});
app.get('/result/:type', function(req,res) {
var o = '';
headresults[req.params.type].forEach(function(i) {
o ='\n' i;
});
o ='\n';
bodyresults[req.params.type].forEach(function(i) {
o ='\n' i;
});
res.send(o);
});
css.html
<!DOCTYPE html>
<html>
<head>
<title>CSS first</title>
<script>var start = Date.now();</script>
<link rel="stylesheet" href="style.css">
<script src="jquery.js"></script>
<script src="test.js"></script>
</head>
<body>
<script>document.write(jsload - start);bodyexec=Date.now()</script>
</body>
</html>
js.html
<!DOCTYPE html>
<html>
<head>
<title>CSS first</title>
<script>var start = Date.now();</script>
<script src="jquery.js"></script>
<script src="test.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script>document.write(jsload - start);bodyexec=Date.now()</script>
</body>
</html>
test.js
var jsload = Date.now();
$(function() {
$.post('/result' location.pathname.replace('.html','') '/' (jsload - start) '/' (bodyexec - start));
});
jquery.js jquery-1.7.1.min.js
Bir tespit "geçersiz tarih" ...
Nasıl JavaScript Tarih nesnesi için 30...
Dinamik olarak nesne JavaScript adlı b...
IE sürümü (9) önce Javascript tespit...
Javascript bugüne kadar önde gelen sıf...