Audyt skryptów JS w 30 sekund

Każdy specjalista SEO wie, że szybkość strony wpływa na ranking i konwersję. Częstym winowajcą problemów z wydajnością jest JavaScript. Skrypty (analityczne, reklamowe, funkcjonalne) mogą blokować renderowanie strony i opóźniać interaktywność. W kilkanaście sekund, bez żadnych skomplikowanych narzędzi możesz przeprowadzić wstępny audyt ładowania skryptów na dowolnej stronie.

render budget async defer

Jak sprawdzić skrypty w konsoli (async/defer) – ultra szybki audyt

3 proste kroki żeby skorzystać ze skryptów:

  1. Wejdź na adres, który chcesz audytować, np. seekio.pl/render-budget/ albo na inną z większą zawartością skryptu (np. nike, google sheets)
  2. Naciśnij F12 (DevTools) -> zakładka Konsola (Console)
  3. Wklej kod i enter.

Poniższy kod wyświetli dokładną listę skryptów wskazując wszystkie <script> na danej stronie. Wyświetli: adres (src), atrybuty async i defer.

Array.from(document.scripts).map(s => ({ src: s.src, async: s.async, defer: s.defer }));

Jednak wersja ta jest mało czytelna, dlatego polecam ulepszoną wersję ze zdecydowanie lepszym UX oraz dodatkową informacją, type=”module”. Skrypty module nie blokują parsera, ponieważ są domyślnie jako defer.

console.table(
  Array.from(document.scripts).map(s => ({
    src: s.src || '[inline]',
    async: s.async,
    defer: s.defer,
    module: s.type === 'module'
  }))
);

Wyświetlanie tylko skryptów potencjalnie blokujących renderowanie

console.table(
  Array.from(document.scripts)
    .filter(s => s.src && s.type !== 'module' && !s.async && !s.defer)
    .map(s => ({ src: s.src, async: s.async, defer: s.defer }))
);

Userscript – najwygodniejsze rozwiązanie

Jestem wielkim fanem rozszerzenia TamperMonkey i mam całkiem sporo różnego rodzaju skryptów zapisanych. O to jeden z nich, który pozwala mi na szybki i przede wszystkim wygodny audyt. Na dole strony pojawia się napis „JS” na czarnym tle, który pokazuje wszystkie dobre i potencjalnie blokujące skrypty wraz ze wszystkimi wymaganymi informacjami.

Skrypt można pobrać bezpośrednio z mojego github. Jeśli już masz rozszerzenie typu TamperMonkey, to wystarczy zainstalować skrypt.

Jak interpretować wyniki

Po wklejeniu kodu w konsoli zobaczysz tabelę z informacjami. Generalnie skrypt blokuje renderowanie strony, jeśli jednocześnie jest z zewnętrznego źródła i ma async: false, defer: false i module: false.

Co oznaczają kolumny

  • src: adres pliku JS. [inline] to skrypt w HTML bez src
  • async: atrybut async (dla classic i module; przy inline nie działa)
  • defer: atrybut defer (działa tylko dla classic zewnętrznych)
  • module: true, gdy type=”module” (dla inline i zewnętrznych)

Najważniejsze zasady

  • module = true
    • Domyślnie zachowuje się jak defer: nie blokuje parsera, wykonuje się po parsowaniu HTML
    • Kolejność między modułami jest zachowana (chyba że dodasz async)
    • async = true przy module -> „async module” – niegwarantowana kolejność względem innych modułów
    • defer przy module jest ignorowane (nie zmienia zachowania)
  • module = false (classic)
    • Zewnętrzny bez async/defer -> potencjalnie blokujący (zatrzymuje parser w miejscu)
    • Zewnętrzny z defer -> nie blokuje – wykona się po parsowaniu, kolejność zachowana
    • Zewnętrzny z async -> nie blokuje – wykona się jak tylko pobierze, kolejność niegwarantowana
    • [inline] (classic) -> wykonuje się natychmiast w miejscu, może blokować parser. Atrybuty async/defer przy inline nie działają (nawet jeśli atrybut widnieje w HTML)

Skrypt blokujący renderowanie

srcasyncdefermodule
https://…/skrypt.jsfalsefalsefalse

Taki wynik jest najgorszy przypadkiem i głównym cel do optymalizacji. Skrypt jest zewnętrzny i nie ma żadnego z atrybutów, które pozwoliłyby przeglądarce ładować go w tle. Przeglądarka zatrzymuje parsowanie HTML -> pobiera ten plik -> wykonuje go i dopiero wtedy wraca do budowania reszty strony.

Wpływ na SEO? Bezpośrednio opóźnia ładowanie widocznych treści, pogarszając Core Web Vitals (FCP, LCP)

Skrypt asynchroniczny (async)

srcasyncdefermodule
https://…/skrypt.jstruefalsefalse

Taki wynik jest prawidłowy, ponieważ atrybut async: true mówi przeglądarce: „Pobierz ten skrypt w tle i uruchom go jak tylko się pobierze”. Jeśli masz kilka skryptów z atrybutem async, zostaną one wykonane w kolejności zakończenia ich pobierania, a nie w kolejności występowania w kodzie. Czyli mniejszy skrypt pobierze się szybciej.

Wpływ na SEO? Pozytywny – skrypt nie blokuje renderowania. Idealny dla zewnętrznych skryptów (analityka, reklamy, widgety, etc), które są niezależne od reszty strony.

Skrypt odroczony (defer)

srcasyncdefermodule
https://…/skrypt.jsfalsetruefalse

To złoty środek dla skryptów modyfikujących stronę. Atrybut defer: true mówi przeglądarce: „Pobierz ten skrypt w tle i poczekaj z jego wykonaniem aż cały HTML zostanie załadowany. Jeśli jest więcej skryptów z defer, wykonaj je w takiej kolejności, w jakiej występują w kodzie”.

Gwarantuje kolejność wykonania, tzn że skrypty wykonają się w takiej samej kolejności, w jakiej znajdują się w kodzie HTML. Skrypt „ma pewność”, że wszystkie elementy HTML (przyciski, formularze, divy) już istnieją, gdy zaczyna działać.

Wpływ na SEO? Idealny, bo nie blokuje renderowania, a jednocześnie ma gwarancję, że uruchomi się, gdy wszystkie elementy strony (DOM) będą już dostępne.

Wydajne rozwiązanie

srcasyncdefermodule
https://…/skrypt.jsfalsefalsetrue

Gdy zobaczysz taki wynik – jest bezpiecznie – można zostawić, bo oznacza, że skrypt został załadowany z type="module". Moduły JavaScript są domyślnie odroczone (defer). Oznacza to, że zachowują się tak, jakby miały atrybut defer, nawet jeśli go nie mają.

Wpływ na SEO? Taki sam jak w przypadku defer: true. Skrypt jest bezpieczny i nie blokuje renderowania.

Skrypt wewnętrzny (inline)

srcasyncdefermodule
[inline]falsefalsefalse

Skrypt jest osadzony bezpośrednio w kodzie HTML i jego wpływ zależy od lokalizacji:

  • W <head> – jeśli jest duży, to może blokować renderowanie. Musi zostać wykonany, zanim przeglądarka przejdzie do <body>
  • Na końcu <body> – strona jest w większości wyrenderowana, więc przeważnie nie ma problemu

Wpływ na SEO? Polecam unikać dużych skryptów inline w sekcji <head>. Jeśli to możliwe, przenieś je do zewnętrznego pliku z atrybutem defer.

Kiedy korzystać z async, a kiedy defer?

To zależy 🙂

Wybór zależy od tego co dany skrypt robi i czy jest zależny od innych skryptów lub elementów na stronie.

Atrybuty async/defer mają jeden wspólny cel – pobranie skryptu w tle, nie blokując przy tym budowania strony. Różnica? Kiedy skrypt zostanie wykonany.

async – dla zewnętrznych skryptów

Używaj go dla skryptów, które są w 100% zewnętrzne i samowystarczalne. Przykłady:

  • Skrypty analityczne – Google Analytics, Hotjar, Clarity
  • Skrypty reklamowe – Google AdSense, Ezoic
  • Wszelkiego rodzaju widgety – np. social media
  • Skrypty firm trzecich (third-party) – czaty, systemy do notyfikacji push, helpdesk

defer – dla zależnych od strony

Używaj go dla skryptów, które muszą wchodzić w interakcję z elementami na stronie, przykłady:

  • Główna logika aplikacji – skrypty, które dodają interaktywność, np. obsługa menu, formularzy, przycisków „kup teraz”, „załaduj więcej”
  • Manipulacja DOM – każdy skrypt, który używa document.getElementById() lub document.querySelector().
  • Biblioteki i frameworki – jeśli ładujesz bibliotekę (np. jQuery, którą można znaleźć na wielu stron opartych o WordPress) i skrypt, który jej używa – oba powinny mieć defer, aby zachować kolejność.
  • Interaktywne elementy – skrypty do sliderów, karuzel, dynamicznych galerii.

Porównanie async vs defer

CechaZwykły <script><script async><script defer>
Blokuje parsowanie HTML?🔴 TAK🟢 NIE🟢 NIE
Kiedy się wykonuje?Od razu i wszystko blokujeGdy się pobierzePo załadowaniu całego HTML
Gwarancja kolejności?🟢 TAK🔴 NIE🟢 TAK
Najlepszy dla…Małych, krytycznych skryptów w <head>Niezależnych skryptów firm trzecichGłównej logiki strony, interakcji

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *