Czy zalecenie włączenia CSS przed JavaScript jest nieprawidłowe?
W niezliczonych miejscach online widziałem zalecenie włączenia CSS przed JavaScript. Rozumowanie jest generalnie tej postaci :
Jeśli chodzi o zamawianie CSS i JavaScript, chcesz swój CSS na pierwszym miejscu. Powodem jest to, że wątek renderujący ma wszystkie informacje o stylu potrzebne do renderowania strony. Jeśli JavaScript includes come first, the javascript engine has to parse it all before kontynuując do następnego zestawu zasobów. Oznacza to, że renderowanie wątek nie może całkowicie pokazać strony, ponieważ nie ma wszystkich style, których potrzebuje.
Moje rzeczywiste testy ujawniają coś zupełnie innego:
Moja uprząż testowa
Używam następującego skryptu Ruby do generowania określonych opóźnień dla różnych zasobów:
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..."
}
Powyższy mini serwer pozwala mi ustawić dowolne Opóźnienia dla plików JavaScript (zarówno serwera jak i klienta) oraz dowolne opóźnienia CSS. Na przykład http://10.0.0.50:8081/test.css?delay=500
daje mi 500 ms opóźnienie transferu CSS.
Używam poniższej strony do testowania.
<!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>
Kiedy dodam CSS jako pierwszy, renderowanie strony zajmuje 1,5 sekundy:
Kiedy włączam JavaScript pierwszy, strona trwa 1,4 sekundy, aby renderować:
Podobne wyniki uzyskuję w Chrome, Firefox i Internet Explorer. W Operze jednak kolejność po prostu nie ma znaczenia.Wygląda na to, że interpreter JavaScript odmawia aby rozpocząć, aż cały CSS zostanie pobrany. Wydaje się więc, że posiadanie JavaScript includes first jest bardziej efektywne, ponieważ wątek JavaScript dostaje więcej czasu wykonywania.
Czy coś mi umyka, czy zalecenie umieszczenia CSS includes przed JavaScript includes nie jest poprawne?
jest oczywiste, że możemy dodać async lub użyć setTimeout, aby zwolnić wątek renderowania lub umieścić kod JavaScript w stopce, lub użyć JavaScript loader. Chodzi tu o uporządkowanie niezbędnych Bity JavaScript i bity CSS w głowicy.
13 answers
To bardzo interesujące pytanie. Zawsze umieszczałem moje CSS <link href="...">
s przed moim JS <script src="...">
S, ponieważ " czytałem kiedyś, że jest lepiej."Tak, masz rację; najwyższy czas zrobić kilka rzeczywistych badań!
Założyłem własną uprząż testową w Node (kod poniżej). Zasadniczo Ja:
- upewnij się, że nie ma buforowania HTTP, więc przeglądarka będzie musiała wykonać pełne pobieranie za każdym razem, gdy strona jest ładowana.
- aby symulować rzeczywistość, włączyłem jQuery i H5BP CSS (więc istnieje przyzwoita ilość skryptów / CSS do analizy)
- Skonfiguruj dwie strony-jedną z CSS przed skryptem, drugą z CSS po skrypcie.
- Zapisano, ile czasu zajęło wykonanie zewnętrznego skryptu w
<head>
do wykonania - zapisałem, jak długo zajęło skrypt inline w
<body>
do wykonania, co jest analogiczne doDOMReady
.
[26]} Opóźnione wysyłanie CSS i / lub skryptu do przeglądarki o 500ms.
- przeprowadziłem test 20 razy w 3 głównych przeglądarki.
Wyniki
Po pierwsze, z opóźnieniem pliku CSS o 500ms:
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
Następnie ustawiłem jQuery na opóźnienie o 500ms zamiast CSS:
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
W końcu ustawiłem zarówno jQuery, jak i CSS, aby opóźnić o 500ms:
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
Wnioski
Po pierwsze, ważne jest, aby pamiętać, że działam przy założeniu, że masz Skrypty znajdujące się w <head>
twojego dokumentu(w przeciwieństwie do końca <body>
). Istnieją różne argumenty dotyczące tego, dlaczego możesz linkować do swoich skryptów w <head>
kontra na końcu dokumentu, ale to poza zakresem tej odpowiedzi. Chodzi wyłącznie o to, czy <script>
s powinny przejść przed <link>
S w <head>
.
W nowoczesnych przeglądarkach desktopowych, wygląda na to, że łączenie się z CSS najpierw nigdy nie zapewnia zwiększenia wydajności. Umieszczenie CSS po skrypcie daje trywialny zysk, gdy zarówno CSS, jak i skrypt są opóźnione, ale daje duże zyski, gdy CSS jest opóźniony. (Pokazane przez kolumny last
w pierwszym zestawie wyników.)
Biorąc pod uwagę, że linkowanie do CSS nie wydaje się szkodzić wydajności, ale Może zapewnić zyski w pewnych okolicznościach, powinieneś linkować do zewnętrznych arkuszy stylów po linkujesz do zewnętrznych skryptów tylko w przeglądarkach desktopowych jeśli wydajność starych przeglądarek nie jest problemem. Czytaj dalej na temat sytuacji mobilnej.
Dlaczego?Historycznie, gdy przeglądarka napotkała znacznik <script>
wskazujący na zewnętrzny zasób, przeglądarka zatrzymała parsowanie HTML, pobrała skrypt, wykonała go, a następnie kontynuowała parsowanie HTML. W przeciwieństwie do tego, jeśli przeglądarka napotkała <link>
dla zewnętrznego arkusza stylów, to kontynuowałaby parsowanie HTML podczas pobierania pliku CSS (równolegle).
Stąd często powtarzana rada, aby najpierw umieścić arkusze stylów – najpierw pobierają, a pierwszy skrypt do pobrania może być ładowane równolegle.
Jednak nowoczesne przeglądarki (w tym wszystkie przeglądarki, które testowałem powyżej) zaimplementowały parsowanie spekulacyjne, gdzie przeglądarka "patrzy do przodu" w HTML i rozpoczyna pobieranie zasobów przed Skrypty pobrać i wykonać.
W starych przeglądarkach bez spekulacyjnego parsowania, umieszczanie skryptów na pierwszym miejscu wpłynie na wydajność, ponieważ nie będą one pobierać równolegle.
Obsługa Przeglądarki
Spekulatywne w 2012 roku, po raz pierwszy zaimplementowano metodę parsowania: (wraz z odsetkiem użytkowników na całym świecie korzystających z tej wersji lub większej od stycznia 2012 roku)
- Chrome 1 (WebKit 525) (100%)
- IE 8 (75%)
- Firefox 3.5 (96%)
- Safari 4 (99%)
- Opera 11.60 (85%)
W przeglądarkach mobilnych trochę trudniej jest uzyskać ostateczne liczby, po prostu ze względu na to, jak heterogeniczny jest krajobraz mobilnej przeglądarki i systemu operacyjnego. Ponieważ Rendering spekulacyjny został zaimplementowany w WebKit 525 (wydany w marcu 2008), a prawie każda warta uwagi przeglądarka mobilna jest oparta na WebKit, możemy stwierdzić, że "większość" przeglądarek mobilnych powinna {69]} go wspierać. Według [[122]}quirksmode , iOS 2.2/Android 1.0 użyj WebKit 525. Nie mam pojęcia jak wygląda Windows Phone.
Jednak przeprowadziłem test na moim urządzeniu z Androidem 4 i chociaż widziałem liczby podobne do wyników pulpitu, podłączyłem go do fantastycznego nowego zdalnego debuggera w Chrome dla Androida, a Karta sieciowa pokazała, że przeglądarka czekała na pobranie CSS, aż JavaScripts zostanie całkowicie załadowany – innymi słowy, {35]}nawet najnowsza wersja JavaScripts nie będzie dostępna. WebKit dla Androida nie wydaje się obsługiwać parsowania spekulacyjnego. podejrzewam, że może być wyłączony z powodu ograniczeń procesora, pamięci i / lub sieci nieodłącznych dla urządzeń mobilnych.
Kod
Wybacz niechlujstwo – to było Q&D.
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-14 16:58:16
Istnieją dwa główne powody, aby umieścić CSS przed JavaScript.
Stare przeglądarki (Internet Explorer 6-7, Firefox 2 itp.) zablokowałby wszystkie kolejne pliki do pobrania, gdy zaczęli pobierać skrypt. Więc jeśli masz
a.js
, a następnieb.css
są pobierane kolejno: najpierw a, potem b. Jeśli maszb.css
, a następniea.js
są pobierane równolegle, więc strona ładuje się szybciej.Nic nie jest renderowane, dopóki nie zostaną pobrane wszystkie arkusze stylów - to prawda we wszystkich przeglądarkach. Skrypty są różne-blokują renderowanie wszystkich elementów DOM, które znajdują się poniżej znacznika script na stronie. Jeśli umieścisz skrypty w nagłówku, oznacza to, że cała strona jest zablokowana przed renderowaniem, dopóki wszystkie arkusze stylów i wszystkie skrypty nie zostaną pobrane. Chociaż ma to sens, aby zablokować wszystkie renderowanie arkuszy stylów (aby uzyskać poprawną stylizację za pierwszym razem i uniknąć flashowania niestylowanej zawartości FOUC), nie ma sensu, aby zablokować renderowanie całej strony do skryptów. Często skrypty nie wpływają na żadne elementy DOM lub tylko część elementów DOM. najlepiej załadować Skrypty tak nisko, jak to tylko możliwe, lub jeszcze lepiej załadować je asynchronicznie.
Fajnie jest tworzyć przykłady z Cuzillion. Na przykład ta strona ma skrypt w nagłówku, więc cała strona jest pusta, dopóki nie skończy się pobieranie. Jeśli jednak przeniesiemy skrypt na koniec BODY block nagłówek strony renderuje się od tych DOM elementy występują nad znacznikiem SCRIPT, jak widać na tej stronie .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-15 07:06:10
Nie chciałbym zbytnio podkreślać wyników, które masz, uważam, że jest to subiektywne, ale mam powód, aby ci wyjaśnić, że lepiej umieścić CSS przed js.
Podczas ładowania strony, są dwa scenariusze, które można zobaczyć:
Przypadek 1: Biały Ekran > niestylowana strona internetowa > stylizowana strona internetowa > interakcja > stylizowana i interaktywna strona internetowa
Przypadek 2: biały ekran > strona nieosłonięta > interakcja > stylizowana strona internetowa > stylizowana i interaktywna strona internetowa
Szczerze mówiąc, nie wyobrażam sobie, żeby ktoś wybrał Przypadek 2. Oznaczałoby to, że odwiedzający korzystający z wolnych połączeń internetowych będą mieli do czynienia z nieutwardzoną stroną internetową, która pozwala im na interakcję z nią za pomocą Javascript (ponieważ jest już załadowana). Co więcej, czas spędzony na patrzeniu na nieuszkodzoną stronę internetową byłby w ten sposób zmaksymalizowany. Dlaczego ktoś miałby tego chcieć?
Działa również lepiej jako jQuery Stany
" przy użyciu Skrypty bazujące na wartości właściwości stylu CSS, ważne jest, aby odwoływać się do zewnętrznych arkuszy stylów lub osadzania stylu elementy przed odwołaniem się do skryptów".
Gdy pliki są ładowane w złej kolejności (najpierw JS, potem CSS), dowolny kod Javascript oparty na właściwościach ustawionych w plikach CSS (na przykład szerokość lub wysokość div) nie zostanie załadowany poprawnie. Wydaje się, że przy niewłaściwej kolejności ładowania prawidłowe właściwości są "czasami" znane Javascript (być może to jest spowodowany stanem rasy?). Efekt ten wydaje się większy lub mniejszy w zależności od używanej przeglądarki.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-14 15:04:32
Czy testy były wykonywane na komputerze osobistym, czy na serwerze WWW? Jest to pusta strona, czy jest to złożony system online z obrazami, bazami danych itp.? Czy Twoje Skrypty wykonują prostą akcję zdarzenia hover, czy są one podstawowym komponentem do tego, jak twoja witryna renderuje i współdziała z użytkownikiem? Jest tu kilka rzeczy do rozważenia, a znaczenie tych zaleceń prawie zawsze staje się regułami, gdy zapuszczasz się w tworzenie stron internetowych o wysokim kalibrze.
Cel zasada "umieść arkusze stylów na górze, a Skrypty na dole" jest taka, że ogólnie jest to najlepszy sposób na uzyskanie optymalnego progresywnego renderowania, co ma kluczowe znaczenie dla doświadczenia użytkownika.
Wszystko inne na bok: zakładając, że twój test jest prawidłowy i naprawdę przynosisz wyniki wbrew popularnym zasadom, nie byłoby to zaskoczeniem, naprawdę. Każda strona internetowa (i wszystko, co potrzebne, aby całość pojawiła się na ekranie użytkownika) jest inna, a Internet jest stale ewoluuje.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-14 06:54:13
Dołączam pliki CSS przed Javascript z innego powodu.
Jeśli mój Javascript musi zrobić dynamiczny rozmiar jakiegoś elementu strony (dla tych narożnych przypadkach, gdzie CSS jest naprawdę głównym z tyłu), a następnie ładowanie CSS po JS jest rdzewieje może prowadzić do warunków wyścigu, gdzie element jest zmieniany przed CSS style są stosowane, a więc wygląda dziwnie, gdy style wreszcie kopać. Jeśli załaduję CSS wcześniej mogę zagwarantować, że rzeczy działają w zamierzonej kolejności i że ostateczny layout jest tym, czym chcę, żeby był.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-14 13:31:29
Czy zalecenie włączenia CSS przed JavaScript jest nieprawidłowe?
Nie, jeśli traktujesz to jako zalecenie. Ale jeśli traktujesz to jako twardą i szybką regułę? tak, jest nieważna.Z https://developer.mozilla.org/en-US/docs/Web/Reference/Events/DOMContentLoaded
Arkusz stylów ładuje wykonanie skryptu blokowego, więc jeśli masz
<script>
po<link rel="stylesheet" ...>
strona nie zakończy parsowania - i DOMContentLoaded nie odpali-dopóki arkusz stylów jest naładowany.
Wygląda na to, że musisz wiedzieć, na czym polega każdy skrypt i upewnić się, że wykonanie skryptu jest opóźnione aż do momentu WŁAŚCIWEGO zakończenia. Jeśli skrypt opiera się tylko na DOM, może zostać wznowiony w ondomready/domcontentloaded, jeśli opiera się na załadowanych obrazkach lub arkuszach stylów, które mają zostać zastosowane, to jeśli poprawnie odczytam powyższy odnośnik, kod musi zostać odroczony do zdarzenia onload.
Nie sądzę, aby jeden rozmiar skarpety pasował do wszystkich, chociaż tak są sprzedawane i Wiem, że jeden rozmiar buta nie pasuje do wszystkich. Nie sądzę, że istnieje ostateczna odpowiedź, na którą należy załadować najpierw, style lub skrypt. Jest to bardziej indywidualna decyzja o tym, co należy załadować w jakiej kolejności i co można odroczyć na później, ponieważ nie znajduje się na"ścieżce krytycznej".
Aby porozmawiać z obserwatorem, który skomentował, że lepiej opóźnić zdolność użytkowników do interakcji, dopóki arkusz nie będzie ładny. Jest Was wielu i denerwujecie Twoje odpowiedniki, które czują coś przeciwnego. Przyszli do witryny, aby osiągnąć cel, a opóźnienia w ich zdolności do interakcji z witryną, czekając na rzeczy, które nie mają znaczenia, aby zakończyć ładowanie, są bardzo frustrujące. Nie mówię, że się mylisz, tylko, że powinieneś być świadomy, że istnieje inna frakcja, która nie podziela twojego priorytetu.
To pytanie dotyczy w szczególności wszystkich reklam umieszczanych na stronach internetowych. Bardzo bym chciał, gdyby autorzy strony renderowali wystarczy umieścić divs dla treści reklamowych i upewnić się, że ich strona została załadowana i interaktywna przed wstrzyknięciem reklam w zdarzeniu onload. Nawet wtedy chciałbym zobaczyć reklamy ładowane seryjnie zamiast wszystkich naraz, ponieważ wpływają one na moją zdolność nawet przewijania zawartości witryny podczas ładowania nadętych reklam. Ale to jest tylko jeden punkt widzenia.
- Poznaj swoich użytkowników i co cenią.
- Poznaj swoich użytkowników i jakie środowisko przeglądania użyj.
- wiedzieć, co robi każdy plik i jakie są jego warunki wstępne. Sprawienie, by wszystko działało będzie miało pierwszeństwo zarówno nad szybkością, jak i nad ładnością.
- Użyj narzędzi, które pokazują linię czasu Sieci podczas tworzenia.
- Przetestuj w każdym ze środowisk, z których korzystają Twoi użytkownicy. Może zaistnieć potrzeba dynamicznej (po stronie serwera, podczas tworzenia strony) zmiany kolejności ładowania w oparciu o środowisko użytkowników.
- w razie wątpliwości, Zmień porządek i wymierz ponownie.
- jest możliwe, że mieszanie stylów i skryptów w kolejności ładowania będzie optymalne; Nie wszystkie z jednego, a wszystkie z drugiego.
- eksperymentuj nie tylko w jakiej kolejności ładować pliki, ale gdzie. Głowa? W Ciele? Po Ciele? DOM gotowy / załadowany? Naładowany?
- rozważ asynchroniczność i odrocz opcje, gdy jest to właściwe, aby zmniejszyć opóźnienie sieci, którego użytkownik doświadczy, zanim będzie mógł wejść w interakcję ze stroną. Test, aby określić, czy pomagają lub boli.
- zawsze będą kompromisy do rozważenia przy ocenie optymalnej kolejności załadunku. Ładna kontra wrażliwa.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-13 22:10:25
Zaktualizowano 2017-12-16
Nie byłem pewien co do testów w OP. postanowiłem trochę poeksperymentować i skończyło się na obalaniu niektórych mitów.
Synchroniczne
<script src...>
zablokuje pobieranie zasobów poniżej do momentu pobrania i wykonania
To już nie jest prawdą . Zobacz wodospad wygenerowany przez Chrome 63:
<head>
<script src="//alias-0.redacted.com/payload.php?type=js&delay=333&rand=1"></script>
<script src="//alias-1.redacted.com/payload.php?type=js&delay=333&rand=2"></script>
<script src="//alias-2.redacted.com/payload.php?type=js&delay=333&rand=3"></script>
</head>
<link rel=stylesheet>
nie zablokuje pobierania i wykonywania Skrypty poniżej
Jest to niepoprawne . Arkusz stylów nie zablokuje pobierania, ale zablokuje wykonywanie skryptu (małe wyjaśnienie tutaj ). Zobacz wykres wydajności wygenerowany przez Chrome 63:
<link href="//alias-0.redacted.com/payload.php?type=css&delay=666" rel="stylesheet">
<script src="//alias-1.redacted.com/payload.php?type=js&delay=333&block=1000"></script>
Mając powyższe na uwadze, wyniki w OP można wyjaśnić w następujący sposób:
CSS First:
CSS Download 500ms:<------------------------------------------------>
JS Download 400ms:<-------------------------------------->
JS Execution 1000ms: <-------------------------------------------------------------------------------------------------->
DOM Ready @1500ms: ◆
Js pierwszy:
JS Download 400ms:<-------------------------------------->
CSS Download 500ms:<------------------------------------------------>
JS Execution 1000ms: <-------------------------------------------------------------------------------------------------->
DOM Ready @1400ms: ◆
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-16 15:32:54
Nie jestem do końca pewien, jak Twój testowy czas "renderowania" w java script. Jednak rozważ to
Jedna strona na twojej stronie to 50k, co nie jest nieuzasadnione. Użytkownik jest na wschodnim wybrzeżu, podczas gdy serwer jest na zachodzie. MTU na pewno nie jest 10k więc będzie kilka wycieczek tam iz powrotem. Otrzymanie strony i arkuszy stylów może zająć 1/2 sekundy. Zazwyczaj (dla mnie) javascript (poprzez wtyczkę jquery i takie) to znacznie więcej niż CSS. Jest również to, co się dzieje, gdy twój połączenie z Internetem dławi się w połowie strony, ale pozwala zignorować to (zdarza mi się to od czasu do czasu i wierzę, że css renderuje, ale nie jestem w 100% pewien).
Ponieważ css jest w głowie, mogą być dodatkowe połączenia, aby go uzyskać, co oznacza, że potencjalnie może zakończyć się przed stroną. Tak czy inaczej podczas pisania pozostała część strony zajmuje i pliki javascript (co jest o wiele więcej bajtów) strona jest niestylowana, co sprawia, że strona/połączenie wydaje się wolne.
Nawet jeśli js interpreter odmawia uruchomienia, dopóki CSS nie zostanie ukończony, czas potrzebny na pobranie kodu javascript, zwłaszcza gdy daleko od serwera jest cięcie na czas css, który sprawi, że strona nie będzie wyglądać ładnie.
To mała optymalizacja, ale to jest powód.
Oto Podsumowanie wszystkich głównych odpowiedzi powyżej (a może poniżej później :)
Dla nowoczesnych przeglądarek, umieść css gdziekolwiek chcesz. Przeanalizują Twój plik html (który nazywają speculative parsing) i zaczną pobierać css równolegle z analizą html.
Dla starych przeglądarek umieszczaj css na górze (jeśli nie chcesz najpierw pokazać nagiej, ale interaktywnej strony).
Dla wszystkich przeglądarek umieść javascript jak najdalej na stronie, ponieważ zatrzyma to parsowanie twojego html. Najlepiej pobrać go asynchronicznie (np. wywołanie ajax)
Istnieją również pewne eksperymentalne wyniki dla konkretnego przypadku, który twierdzi, że stawianie javascript na pierwszym miejscu (w przeciwieństwie do tradycyjnej mądrości stawiania CSS na pierwszym miejscu) daje lepszą wydajność, ale nie ma dla niego logicznego rozumowania i nie ma walidacji dotyczącej szerokiego zastosowania, więc możesz ją zignorować na razie.
Więc, aby odpowiedzieć na pytanie: tak. Zalecenie do Dołącz CSS przed JS jest nieprawidłowy dla nowoczesnych przeglądarek. Umieść CSS, gdzie chcesz, i umieścić JS pod koniec, jak to możliwe.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-13 14:05:37
Steve Souders już dał ostateczną odpowiedź, ale...
Zastanawiam się, czy nie ma problemu zarówno z oryginalnym testem sama, jak i powtórzeniem Josha.
Wydaje się, że oba testy zostały przeprowadzone na połączeniach o niskim opóźnieniu, gdzie ustawienie połączenia TCP będzie miało trywialny koszt.
Jak to wpływa na wynik testu nie jestem pewien i chciałbym spojrzeć na wodospady dla testów przy "normalnym" połączeniu latencji, ale...
Pierwszy plik pobrany powinien uzyskać połączenie używane dla strony html, a drugi pobrany plik otrzyma nowe połączenie. (Flushing the early alters that dynamic, but it ' s not being done here)
W nowszych przeglądarkach drugie połączenie TCP jest otwierane spekulatywnie, więc narzut połączenia jest zmniejszany / znikany, w starszych przeglądarkach nie jest to prawdą i drugie połączenie będzie miało narzut otwarcia.
Całkiem jak/jeśli to wpływa na wynik testów Nie jestem pewien.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-12 20:46:41
Myślę, że to nie będzie prawda dla wszystkich przypadków. Ponieważ css pobierze równolegle, ale js nie może. Rozważmy dla tego samego przypadku,
Zamiast mieć pojedynczy css, weź 2 lub 3 pliki css i wypróbuj je w ten sposób,
1) css..css..js 2) css..js..css 3) js..css..css
Na pewno css..css..js da lepszy wynik niż wszystkie inne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-23 08:33:35
Musimy pamiętać, że nowe przeglądarki pracowały na swoich silnikach Javascript, parserach itd., optymalizując wspólne problemy z kodem i znacznikami w taki sposób, że problemy występujące w starożytnych przeglądarkach, takich jak
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-14 14:29:02
osobiście nie kładłbym zbyt dużego nacisku na taką "mądrość ludową."To, co mogło być prawdą w przeszłości, może nie być prawdą teraz. Zakładam, że wszystkie operacje związane z interpretacją i renderowaniem strony internetowej są w pełni asynchroniczne ("pobieranie" czegoś i "działanie na to" to dwie zupełnie różne rzeczy, które mogą być obsługiwane przez różne wątki, itp.), a w każdym razie całkowicie poza Twoją kontrolą lub twoją troską.
I ' d put Odniesienia do CSS w części "head" dokumentu, wraz z wszelkimi odniesieniami do zewnętrznych skryptów. (Niektóre skrypty mogą wymagać umieszczenia w ciele, a jeśli tak, zobowiązują je.)
Poza tym ... jeśli zauważysz, że "to wydaje się być szybsze/wolniejsze niż to, w tej/tamtej przeglądarce", potraktuj tę obserwację jako interesującą, ale nieistotną ciekawostkę i nie pozwól, aby wpływała ona na twoje decyzje projektowe. Zbyt wiele rzeczy zmienia się zbyt szybko. (ktoś chce obstawiać ile minut to będzie zanim zespół Firefoksa wyjdzie z kolejną tymczasową wersją swojego produktu? Ja też nie.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-14 04:08:14