Poprawić wydajność strony internetowej poprzez równoległe pobieranie CSS?

15

Optymalizowałem czas wczytywania strony w witrynie. Jednym ze sposobów było połączenie wielu żądań HTTP dla CSS w jedno połączone żądanie HTTP. Ale jeden z recenzentów zadał interesujące pytanie: czy paralelizacja pobierania wielu plików CSS nie skróciłaby czasu ładowania strony?

Nigdy nie zastanawiałem się nad tą opcją, ponieważ jedyne, co czytam w Internecie, to to, że zmniejszenie liczby (blokujących) żądań HTTP jest kluczem do szybszej strony internetowej (chociaż Google Pagespeed Insights nie wydaje się jasno to określać 1 ).

Widzę kilka powodów, dla których paralelizacja nie poprawiłaby wydajności lub miała tylko bardzo małe znaczenie (przewaga korzyści z używania mniejszej liczby żądań HTTP):

  • Ustanowienie nowego połączenia jest kosztowne. Chociaż konfigurowanie wielu połączeń może odbywać się równolegle, przeglądarki używają co najwyżej około 4-6 połączeń (w zależności od przeglądarki), więc równoległe pobieranie CSS zablokowałoby pobieranie innych zasobów, takich jak JavaScript i obrazy.
  • Konfiguracja połączenia HTTPS wymaga dodatkowych danych. Przeczytałem, że może to być z łatwością kilka KB danych. To dodatkowe dane, które należy przesłać przewodowo, zamiast CSS, który faktycznie chcemy wysłać.
  • Ze względu na algorytm TCP Slow Start, im więcej danych zostanie wysłanych przez połączenie, tym szybsze będzie połączenie. Tak długo trwające połączenia faktycznie wysyłałyby dane znacznie szybciej niż nowe połączenia. Zobacz na przykład protokół SPDY, który wykorzystuje pojedyncze połączenie w celu poprawy czasów ładowania strony.
  • TCP jest abstrakcją: nadal istnieje (zwykle) tylko jedno podstawowe połączenie. Tak więc, gdy używanych jest wiele żądań, dane przesyłane przewodowo niekoniecznie korzystają z wielu połączeń w celu poprawy prędkości.
  • Połączenia internetowe są z natury zawodne, zwłaszcza na urządzeniach mobilnych. Jedno żądanie może zostać zakończone znacznie szybciej niż drugie. Korzystanie z wielu żądań CSS oznacza, że ​​renderowanie strony internetowej jest blokowane do czasu zakończenia ostatniego żądania, co może być znacznie późniejsze niż przeciętne połączenie.

Czy jest więc jakaś korzyść z równoległego żądania HTTP dla plików CSS?

Uwaga / aktualizacja: wszystkie pliki CSS blokują renderowanie. Pliki CSS, które nie zostały jeszcze przeniesione poza ścieżkę krytyczną.

ayke
źródło
Widziałem coś w kodzie Etsy jako strony rzemieślniczej, w której zalecali użycie jednej domeny bez plików cookie dla obiektów statycznych (css, imgs, js). Okazuje się, że nowoczesne przeglądarki świetnie sobie radzą z równoległymi pobraniami z jednej domeny. Jeśli chodzi o wiele plików z tej samej domeny (10 plików css vs 1 duży), myślę, że lepiej jest połączyć i zminimalizować jeden duży plik i po prostu zrobić z niego jedno żądanie. Zwłaszcza w CSS, gdzie Twoja strona prawdopodobnie będzie potrzebować całego css, aby wyglądać poprawnie.
Frank
W pewien sposób przeglądarki już pobierają równolegle na podstawie liczby dostępnych połączeń do użycia. Opiera się na HTML, który czyta przeglądarka.
niedz.

Odpowiedzi:

14

Pliki CSS połączone z dokumentami HTML są dodawane do równoległej kolejki pobierania podczas analizowania HTML; najważniejsze jest to, że niesynchroniczne łącza JavaScript blokują parser HTML, zapobiegając dodawaniu późniejszych znaczników do kolejki pobierania, dopóki JavaScript nie zostanie pobrany, przeanalizowany i wykonany. [1]

Oto przykład, który zmusza przeglądarkę do pobierania kolejno trzech z czterech plików (co najmniej trzy trasy w obie strony):

<head>
  <script src="js/fizz.js"></script>
  <link rel="stylesheet" href="css/foo.css"/>
  <script src="js/buzz.js"></script>
  <link rel="stylesheet" href="css/bar.css"/>
</head>

Oto przykład przerobiony, aby wszystkie 4 pliki były pobierane równolegle (co najmniej jedna podróż w obie strony):

<head>
  <link rel="stylesheet" href="css/foo.css"/>
  <link rel="stylesheet" href="css/bar.css"/>
  <script async src="js/fizz.js"></script>
  <script src="js/buzz.js"></script>
</head>

Kolejna uwaga: pliki CSS (domyślnie) blokują renderowanie, a nie blokują parser; strona będzie nadal analizowana i konstruowany DOM, ale renderowanie nie rozpocznie się, dopóki nie zostanie zbudowana CSSOM.

Głównym powodem podzielenia twojego CSS jest uzyskanie minimalnych reguł niezbędnych do renderowania treści widocznej na ekranie dla klienta i parsowanie tak szybko, jak to możliwe. Pozostałe reguły dotyczące rzeczy, które nie są od razu widoczne, można oznaczyć jako niekoniecznie blokujące renderowanie za pomocą mediazapytań w tagu link lub dodać do strony przez asynchronicznie załadowany JavaScript.

Tak więc nie ma wyraźnej korzyści z równoległego pobierania plików CSS dla samej korzyści. Ale jak zawsze mierz i testuj!

Do dalszego czytania polecam te artykuły na temat „Podstawy sieci: Optymalizacja wydajności” od Google: https://developers.google.com/web/fundamentals/performance/

[1]: To ignoruje funkcję analizy spekulacyjnej w niektórych przeglądarkach:

https://docs.google.com/document/d/1JQZXrONw1RrjrdD_Z9jq1ZKsHguh8UVGHY_MZgE63II/preview?hl=en-GB&forcehl=1

https://developer.mozilla.org/en-US/docs/Web/HTML/Optimizing_your_pages_for_speculative_parsing

Robert K. Bell
źródło
1
Kolejna dobra lektura dotycząca sposobu jednoczesnego pobierania skryptów znajduje się tutaj: stackoverflow.com/questions/436411/…
joshreesjones
Warto zauważyć, że wszystkie pliki .js powinny być połączone na końcu kodu tuż przed zamykającym znacznikiem body, aby nie blokowały niczego.
Chaoley
czy możesz rozwinąć „Więc nie ma wyraźnej korzyści z równoległego pobierania plików CSS tylko dla samej korzyści”? Jakoś nie mogłem tego zrozumieć z powyższej odpowiedzi
gaurav5430
@ gaurav5430 Wydaje się, że nie ma dobrych powodów do dzielenia plików css, poza optymalizacją dla czasu renderowania powyżej zakładki (a może optymalizacji pamięci podręcznej?)
Robert K. Bell