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&amp;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:

CSS first

Kiedy włączam JavaScript pierwszy, strona trwa 1,4 sekundy, aby renderować:

JavaScript first

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.

Author: Community, 2012-02-14

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 do DOMReady.
  • [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 sumie około 85% używanych obecnie przeglądarek desktopowych obsługuje ładowanie spekulacyjne. Umieszczanie skryptów przed CSS będzie miało karę za wydajność na 15% użytkowników globalnie ; YMMV na podstawie konkretnych odbiorców Twojej witryny. (I pamiętaj, że liczba maleje.)

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

 677
Author: josh3736,
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.

  1. 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ępnie b.css są pobierane kolejno: najpierw a, potem b. Jeśli masz b.css, a następnie a.js są pobierane równolegle, więc strona ładuje się szybciej.

  2. 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 .

 293
Author: Steve Souders,
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.

 40
Author: defau1t,
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.

 25
Author: sunday,
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ł.

 21
Author: hugomg,
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.
 10
Author: Ted Cohen,
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&amp;delay=333&amp;rand=1"></script>
<script src="//alias-1.redacted.com/payload.php?type=js&amp;delay=333&amp;rand=2"></script>
<script src="//alias-2.redacted.com/payload.php?type=js&amp;delay=333&amp;rand=3"></script>
</head>

Chrome net inspector - > waterfall

<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&amp;delay=666" rel="stylesheet">
<script src="//alias-1.redacted.com/payload.php?type=js&amp;delay=333&amp;block=1000"></script>

Chrome Dev tools - > wydajność


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:                                                                                                                                            ◆
 6
Author: Salman A,
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.

 4
Author: ,
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 22:33:38

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.

 2
Author: mehmet,
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.

 1
Author: Andy Davies,
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.

 1
Author: harishkumar329,
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

 0
Author: George Katsanos,
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.)

 -5
Author: user106701,
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