„Eliminacja kodu CSS blokującego renderowanie w części strony widocznej na ekranie”

153

Korzystam ze statystyk Google PageSpeed, aby spróbować poprawić wydajność mojej witryny i do tej pory okazało się, że jest ona niezwykle skuteczna. Rzeczy takie jak odraczanie skryptów działały pięknie, ponieważ miałem już wewnętrzną wersję jQuery, .ready()aby odraczać skrypty do pełnego załadowania strony, wszystko, co musiałem zrobić, to wstawić tę konkretną funkcję i przenieść pełne skrypty na koniec strony. To działało świetnie.

Ale teraz widzę jedną pozostałą żółtą kropkę na liście kontrolnej: „Eliminacja kodu CSS blokującego renderowanie w części strony widocznej na ekranie”.

Sposób, w jaki skonfigurowany jest mój CSS, polega na tym, że ma jeden globalny _.cssplik zawierający style, które dotyczą ogólnie struktury strony lub są używane w więcej niż jednym lub dwóch miejscach w witrynie. Większość stron ma wówczas powiązany plik CSS (na przykład party.phpma party.css) zawierający style specyficzne dla tej konkretnej strony. Wszystkie pliki CSS są buforowane na czas nieokreślony, ponieważ dodaję je /t=FILEMTIMEdo nazw plików (a później usuwam je za pomocą .htaccess), aby zagwarantować, że pliki zostaną zaktualizowane, gdy zostaną zmienione.

W każdym razie Google zaleca wstawianie stylów krytycznych potrzebnych do wyświetlania treści widocznych na ekranie. Problem w tym, że ... cóż, spójrz na ten zrzut ekranu: http://prntscr.com/1qt49e

Jak widać ... CAŁA zawartość jest widoczna na ekranie! Ludzie nienawidzą przewijania, szczególnie w grach, które wymagają ładowania wielu stron. Tak więc zaprojektowałem witrynę tak, aby mieściła się na jednym ekranie (zakładając wystarczająco dobrą rozdzielczość). Oznacza to, że ... WSZYSTKIE style mają zastosowanie do treści widocznych na ekranie! Więc ... czy jest jakieś rozwiązanie? A może utknąłem z żółtym znakiem na prawie idealnym wyniku?

Niet the Dark Absol
źródło
to ironia losu, że ładowanie tej zawartości ekranu widocznej na ekranie zajmuje dużo czasu :) W rzeczywistości zrzut ekranu nigdy się nie załadował
Anupam
@Anupam Prawdopodobnie został usunięty. Prntscr nie jest dokładnie oznaczało dla trwałości, a ja nie spodziewałem się to pytanie być zupełnie tak popularne.
Niet the Dark Absol
tak, wszystko dobrze, to był tylko lekki komentarz
Anupam

Odpowiedzi:

182

Podobne pytanie zadawano już wcześniej: Co to jest „treść widoczna na ekranie” w Google Pagespeed?

Po pierwsze, musisz zauważyć, że chodzi o „ strony mobilne ”.
Więc kiedy poprawnie zinterpretowałem twoje pytanie i zrzut ekranu, to nie jest dla twojej witryny!

Wręcz przeciwnie - wykonanie niektórych czynności zalecanych przez Google w ich wytycznych pogorszy sytuację w przypadku „normalnych” witryn internetowych.
I nie wszystko, co pochodzi z Google, jest „świętym Graalem” tylko dlatego, że pochodzi z Google. A oni sami nie są dobrym wzorem do naśladowania, jeśli spojrzeć na ich znaczniki HTML.

Najlepsza rada, jaką mogę ci dać, to:

  • Ustaw szerokość i wysokość zastępowanych elementów w swoim CSS, aby przeglądarka mogła rozmieścić elementy i nie musiała czekać na zastąpioną zawartość!

Poza tym, dlaczego używasz różnych plików CSS, a nie tylko jednego?
Dodatkowe żądanie jest gorsze niż mała ilość danych. A po pierwszym żądaniu plik CSS i tak jest buforowany.

Zawsze należy zadbać o:

  • maksymalnie zmniejsz liczbę żądań
  • utrzymuj ogólną wagę strony na jak najniższym poziomie

I nie zastanawiaj się, jak zdobyć 100% narzędzia Google PageSpeed ​​Insights ...! ;-)

Dodatek 1: Oto strona, na której Google pokazuje nam, co zaleca dla optymalizacji dostarczania CSS .

Jak powiedziałem wcześniej, nie sądzę, aby to było ani realistyczne, ani sensowne dla „normalnej” witryny internetowej! Ponieważ głównie w przypadku responsywnego projektu strony internetowej z całą pewnością używasz zapytań o media i innych stylów układu. Więc jeśli nie zamierzasz najpierw załadować swojego CSS i w sposób blokujący, otrzymasz FOUT ( Flash Of Unstyled Text ). Naprawdę nie wierzę, że jest to „lepsze” niż przynajmniej kilka milisekund na renderowanie strony!

Imho Google rozpoczyna nowy „szum” (kiedy spojrzę na wszystkie pytania na ten temat w Stackoverflow)…!

Netsurfer
źródło
9
Świetna odpowiedź. Problem w tym, że Google wydaje się karać, jeśli masz wolniejszą stronę. Dlatego zmuszają cię do trzymania się ich pomysłów, niezależnie od tego, czy są to świetne, czy całkowicie głupie. :(
Steve Horvath
10
@Netsurfer nie wszystko, co pochodzi z Google, to „Święty Graal” LOL. Drapałem się po głowie, aby osiągnąć 100, ale po przeczytaniu tego komentarza zatrzymałem się na 92.
kiranking
44
Należy bardziej podkreślić fakt, że Google nie stosuje się do własnych sugestii .
Pan Smith
2
Dodatkowe żądania staną się mniej problematyczne z HTTP / 2 i SPDY, z Wikipedii , „Dodatkowe ulepszenia wydajności w pierwszej wersji roboczej HTTP / 2 (która była kopią SPDY) pochodzą z multipleksowania żądań i odpowiedzi w celu uniknięcia problem z blokowaniem linii w HTTP 1 (nawet gdy używane jest potokowanie HTTP), kompresja nagłówków i priorytetyzacja żądań. "
RationalDev lubi GoFundMonica
3
próbowałem podnieść moją stronę z 72 urządzeń mobilnych i 80 komputerów stacjonarnych, ale miałem ten sam problem. Odmawiam umieszczania mojego css niżej i prawdopodobnie obniżam komfort użytkowania, wyświetlając FOUT!
wiadomości
14

Jak uzyskałem 99/100 w Google Page Speed ​​(dla telefonów komórkowych)

TLDR: Kompresuj i osadzaj cały skrypt CSS między <style></style>tagami.


Od tygodnia ścigam ten nieuchwytny wynik 100/100. Podobnie jak Ty, ostatnim pozostałym elementem była eliminacja „CSS blokującego renderowanie dla zawartości strony widocznej na ekranie”.

Z pewnością istnieje łatwe rozwiązanie? Nie. Starałem się loadCSS grupy żarnika za rozwiązanie. Za dużo .js jak na mój gust.

A co z asyncatrybutami css (np. Js)? Oni nie istnieją.

Byłem gotowy się poddać. Wówczas mnie olśniło. Jeśli połączenie skryptu blokowało renderowanie, co jeśli zamiast tego osadziłbym cały mój css w głowie. W ten sposób nie było nic do zablokowania.

Wydawało się absolutnie NIEPOPRAWNE umieszczanie 1263 linii CSS w moim tagu stylu. Ale dałem temu wir. Skompresowałem go (i dodałem przedrostkiem) najpierw używając:

postcss -u autoprefixer --autoprefixer.browsers 'last 2 versions' -u cssnano --cssnano.autoprefixer false *.css -d min/ Zobacz pakiet NPM postcss .

Teraz była to tylko jedna DŁUGA linia bez spacji css. Umieściłem css w <style>your;great-wall-of-china-long;css;here</style>tagach na mojej stronie głównej. Następnie ponownie przeanalizowałem informacje o szybkości strony.

Poszedłem z 90/100 do 99/100 na komórce !!!

To jest sprzeczne ze wszystkim we mnie (i prawdopodobnie w tobie). Ale to rozwiązało problem. Używam go na razie na mojej stronie głównej i programowo dołączam skompresowany CSS za pomocą PHP include.

YMMV (Twój przebieg może się różnić) w oczekiwaniu na długość Twojego CSS. Google może cię oszukiwać za zbyt dużą zawartość ekranu. Ale nie zakładaj; test!

Uwagi

  1. Na razie robię to tylko na mojej stronie domowej, aby ludzie mogli szybko renderować moją najważniejszą stronę.

  2. Twój plik css nie zostanie zapisany w pamięci podręcznej. Nie martwię się jednak zbytnio. Gdy tylko trafią na inną stronę w mojej witrynie, plik .css zostanie zapisany w pamięci podręcznej (patrz uwaga 1).

elbowlobstercowstand
źródło
4
Dziękuję za poświęcenie i badania, jednak osobiście nie będę o tym śnił: D
Niet the Dark Absol
2
Więc po co, poza próbą osiągnięcia wyniku, który tak naprawdę nic nie pomoże?
LarryBud,
Fajnie, że masz wyższy wynik, ale teraz każda strona w Twojej witrynie będzie miała większą wagę. Mimo to, dobre znalezisko.
EdwardM
@EdwardM Thanks! Zobacz moją notatkę 2 w poście. Po przejściu na drugą stronę css zostaje zapisany w pamięci podręcznej, a problem z wagą znika.
elbowlobstercowstand
1
@LarryBud Punkt wyższego wyniku? Więcej pieniędzy dla mnie. Im wyżej moja witryna jest w Google, tym większe prawdopodobieństwo, że ktoś ją kliknie i zostanie klientem. Ponieważ Google używa szybkości strony do określania rankingu , postanowiłem poprawić swój wynik.
elbowlobstercowstand
9

Kilka wskazówek, które mogą pomóc:

  • Wczoraj natknąłem się na ten artykuł o optymalizacji CSS: Profilowanie CSS dla ... optymalizacji
    Wiele przydatnych informacji o CSS i tym, co CSS powoduje największe straty wydajności.

  • Widziałem następującą prezentację w jQueryUK na temat „ukrytych tajemnic” w narzędziach deweloperskich Google Chrome (Canary): DevTools potrafią to zrobić . Sprawdź sekcje o Czas do pierwszego malowania , przemalowywanie i kosztowne CSS.

  • Ponadto, jeśli używasz programu ładującego, takiego jak requireJS, możesz rzucić okiem na jedną z wtyczek ładujących CSS, zwaną require-CSS , która wykorzystuje CSSO - optymalizator, który również przeprowadza optymalizację strukturalną, np. łączenie bloków o identycznych właściwościach. Użyłem go kilka razy i może zaoszczędzić sporo CSS od przypadku do przypadku.

Bez pytania: popieram @Enzino w tworzeniu sprite'a dla wszystkich małych ikon, które ładujesz. Rozmiary plików są tak małe, że nie gwarantuje to wymiany serwera w obie strony dla każdej ikony. Należy również pamiętać o łącznej liczbie równoczesnych żądań HTTP, które może wykonać przeglądarka. Dlatego też żądania większej liczby małych ikon „blokują renderowanie”. Chociaż pusta strona w porównaniu do twojej, podoba mi się, jak ładuje się duckduckgo .

częsty
źródło
Wydaje się, że duckduckgo również nie dba o ich wynik strony, sprawdź tutaj
Chetabahana
6

Proszę spojrzeć na następującą stronę https://varvy.com/pagespeed/render-blocking-css.html . Pomogło mi to pozbyć się "CSS blokującego renderowanie" . Użyłem poniższego kodu, aby usunąć " Render Blocking CSS ". Teraz w Google page speed insight nie dostaję problemu związanego z blokowaniem renderowania css.

<!-- loadCSS -->
<script src="https://cdn.rawgit.com/filamentgroup/loadCSS/6b637fe0/src/cssrelpreload.js"></script>
<script src="https://cdn.rawgit.com/filamentgroup/loadCSS/6b637fe0/src/loadCSS.js"></script>
<script src="https://cdn.rawgit.com/filamentgroup/loadCSS/6b637fe0/src/onloadCSS.js"></script>
<script>
      /*!
      loadCSS: load a CSS file asynchronously.
      */
      function loadCSS(href){
        var ss = window.document.createElement('link'),
            ref = window.document.getElementsByTagName('head')[0];

        ss.rel = 'stylesheet';
        ss.href = href;

        // temporarily, set media to something non-matching to ensure it'll
        // fetch without blocking render
        ss.media = 'only x';

        ref.parentNode.insertBefore(ss, ref);

        setTimeout( function(){
          // set media back to `all` so that the stylesheet applies once it loads
          ss.media = 'all';
        },0);
      }
      loadCSS('styles.css');
    </script>
    <noscript>
      <!-- Let's not assume anything -->
      <link rel="stylesheet" href="styles.css">
    </noscript>
Amuk Saxena
źródło
1
Kiedy używam wspomnianej funkcji, zmniejsza to wynik pageSpeed. Funkcja, którą napisałem, to: jsfiddle.net/kvfzbxxo Czy możesz mi pomóc?
arsho
Zaimplementowałem tę samą funkcję na następującym adresie URL i proszę spojrzeć na prędkość tutaj " whitecashback.in ", możesz spojrzeć na adres URL źródła i znaleźć funkcję "loadCSS" w stopce. Pomoże ci to zrozumieć, w jaki sposób zaimplementowałem kod. Szybkość strony powinna wzrosnąć, gdy css ładuje się po stronie.
Amuk Saxena,
Użyłem tego kodu: jsfiddle.net/sbpa1hun. Teraz CSS nie jest ładowany na stronie.
arsho
Wspomniałem, że po dodaniu tego kodu: jsfiddle.net/sbpa1hun, który jest używany w Twojej witrynie, moja strona straciła wszystkie style. Zwiększa to szybkość strony, ale CSS już nie działa! Możesz mi jakoś pomóc? Szybkość stron wynosi około 40. Ale dodając twój kod mam około 70. Ale nie mogłem uruchomić CSS.
arsho
1
Jeśli próbujesz to zrobić w jsfiddle, to nie zadziała, wypróbuj ten kod w swojej witrynie, jsfiddle zablokuje ładowanie css dla zewnętrznych stron internetowych. Ponieważ ładujesz css ze źródeł zewnętrznych za pomocą javascript. Więc spróbuj zrobić to w swojej witrynie. Spróbuj także dołączyć pliki jquery, których brakuje w twoim skrypcie. Po dołączeniu plików js może to zadziałać. Należy również pamiętać, że witryny https mogą działać w jsfiddle. Otrzymujesz ten błąd: „Zablokowano ładowanie mieszanej zawartości aktywnej”. Najpierw musisz rozwiązać ten problem.
Amuk Saxena,
4

Ja też zmagałem się z tym nowym wskaźnikiem szybkości stron.

Chociaż nie znalazłem praktycznego sposobu na przywrócenie mojego wyniku do 100%, jest kilka rzeczy, które okazały się pomocne.

Połączenie całego pliku CSS w jeden plik bardzo pomogło. Wszystkie moje witryny mają kopie zapasowe do% 95 -% 98.

Jedyną inną rzeczą, o której mogłem pomyśleć, było umieszczenie wszystkich niezbędnych CSS (które wydaje się być ich większością - przynajmniej na moich stronach) na pierwszej stronie, aby uzyskać wspaniały wysoki wynik. Chociaż może to pomóc w uzyskaniu wyniku szybkości, prawdopodobnie spowoduje to wolniejsze ładowanie strony.

Glipt
źródło
2
Magazyn rozbijania ma wynik 100% w Pagespeed testu developers.google.com/speed/pagespeed/insights/...
Mo.
1

Optymalnym rozwiązaniem w 2019 roku jest serwer HTTP / 2 Push .

Nie potrzebujesz żadnych hackerskich rozwiązań javascript ani stylów wbudowanych. Potrzebujesz jednak serwera obsługującego protokół HTTP 2.0 (każda nowoczesna wersja serwera będzie to robić), który sam wymaga, aby serwer obsługiwał SSL. Jednak w przypadku Let's Encrypt i tak nie ma powodu, aby nie używać SSL.

Moja witryna https://r.je/ ma wynik 100/100 zarówno dla telefonów komórkowych, jak i komputerów.

Przyczyną tych błędów jest to, że przeglądarka pobiera kod HTML, a następnie musi poczekać na pobranie kodu CSS, zanim strona będzie mogła zostać wyrenderowana. Korzystając z protokołu HTTP2, możesz wysłać jednocześnie HTML i CSS.

Możesz użyć HTTP / 2 push, ustawiając nagłówek Link.

Przykład Apache (.htaccess):

Header add Link "</style.css>; as=style; rel=preload, </font.css>; as=style; rel=preload"

W przypadku NGINX możesz dodać nagłówek do tagu lokalizacji w konfiguracji serwera:

location = / {
    add_header Link "</style.css>; as=style; rel=preload, </font.css>; as=style; rel=preload";
}

Z tym ustawionym nagłówkiem przeglądarka otrzymuje jednocześnie HTML i CSS, co powstrzymuje CSS przed blokowaniem renderowania.

Będziesz chciał go dostosować tak, aby kod CSS był wysyłany tylko przy pierwszym żądaniu, ale nagłówek łącza jest najbardziej kompletnym i najmniej hakerskim rozwiązaniem „Eliminacja JavaScript i CSS blokowania renderowania”

Aby uzyskać szczegółowe omówienie, spójrz na mój post tutaj: Eliminacja blokowania renderowania CSS przy użyciu protokołu HTTP / 2 Push

Tom B.
źródło
Mogę się mylić, ale czy wypychanie serwera nie powodowałoby wysyłania CSS za każdym razem, gdy ładujesz stronę, a nie tylko raz przed zapisaniem w pamięci podręcznej?
Niet the Dark Absol
Tak, istnieje kilka technik, takich jak pliki cookie, które mogą pomóc tego uniknąć. Spójrz na sekcję dotyczącą selektywnego pchania tutaj: nginx.com/blog/nginx-1-13-9-http2-server-push
Tom B
-1

Cześć, dla jQuery Możesz używać tylko w ten sposób

Używaj tylko async i type = "text / javascript"

Rajeev
źródło