Przejdź do treści

PERFORMANCE · 4 MIN

Lighthouse 95+ na mobile — co naprawdę działa, a co jest mitem

Mit „pluginu cache" i co realnie poprawia performance. Asset cache busting, lazy loading, font preload, defer JS. Z miarami.

·

Standardowa rada w forumach WordPressa: „Dodaj WP Rocket, masz Lighthouse 95″. Mit, którego nie warto powtarzać.

WP Rocket może pomóc. Ale w 2026 roku, na świeżej instalacji WordPressa z custom motywem, sam plugin cache nie zrobi z 60 → 95. Co naprawdę działa, w kolejności impactu:

1. Custom motyw zamiast page-buildera

Największy single change. Strona z Elementor Pro = 3MB JS bundle przed pierwszym zdjęciem hero. Custom motyw = 30-80KB.

JS to najwolniejszy zasób. Każdy kilobajt JS-a kosztuje na 4G mobile ~20ms decode + parse + execute. 3MB = 60+ sekund pracy CPU mobilnego (rozłożone na ~6 sekund real time, ale blockuje wątek główny).

Lighthouse to widzi. Total Blocking Time i Time to Interactive to dwie metryki, które najmocniej zostaną zniszczone przez ciężki JS.

2. Image optimization — WebP + width/height

Drugi największy impact. Hero image 200KB w JPG vs 80KB w WebP. Pomnóż przez 8-12 zdjęć na średniej stronie.

W kodzie:

add_action('add_attachment', function($attachment_id) {
    if (!class_exists('Imagick')) return;
    $file = get_attached_file($attachment_id);
    if (!preg_match('/.(jpe?g|png)$/i', $file)) return;

    $webp_path = preg_replace('/.(jpe?g|png)$/i', '.webp', $file);
    $img = new Imagick($file);
    $img->setImageFormat('webp');
    $img->setImageCompressionQuality(82);
    $img->writeImage($webp_path);
});

Dodatkowo: zawsze ustaw width + height na <img>. To zapobiega CLS (Cumulative Layout Shift). Bez tego strona „skacze” gdy obrazek się załaduje — Lighthouse to karze.

3. Asset cache busting przez filemtime()

Zamiast pluginu cache — natywny mechanizm WordPressa:

$css_path = get_template_directory() . '/style.css';
$css_ver  = file_exists($css_path) ? filemtime($css_path) : '1.0';
wp_enqueue_style('theme', get_stylesheet_uri(), [], $css_ver);

Dla przeglądarki: po pierwszej wizycie CSS jest w cache (header Cache-Control: max-age=31536000). Przy nowym deployu — filemtime się zmienia, URL się zmienia, przeglądarka pobiera nowy plik. Zero konfiguracji, zero pluginu.

4. Critical CSS inline

Above-the-fold CSS w <head> jako <style>. Reszta CSS-a ładuje się asynchronicznie.

Ręczne wycinanie krytycznego CSS-a jest ogarniaczem czasu. Narzędzie critical (npm) automatyzuje to przy build:

npx critical 
  --base ./public 
  --src https://stronka.pl 
  --target ./public/critical.css 
  --width 1280 --height 800

Wynik: pierwsze ~1500 znaków CSS (header, hero) wpada inline, reszta ładuje się <link rel="preload" as="style" onload="this.rel='stylesheet'">.

5. Font preload + display swap

Fonty to często killery LCP. Geist 400 + 600 (200KB) ładowany w `font-display: swap` ze „ w head daje LCP poprawiony o 300-600ms.

<link rel="preload" as="font" type="font/woff2" crossorigin
      href="/assets/fonts/Geist-Regular.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
      href="/assets/fonts/Geist-SemiBold.woff2">

I w CSS:

@font-face {
    font-family: 'Geist';
    src: url('/fonts/Geist-Regular.woff2') format('woff2');
    font-display: swap;
}

6. Defer JS

Wszystko poza krytycznym JS (np. cookie banner) leci z atrybutem defer:

add_filter('script_loader_tag', function($tag, $handle) {
    if (in_array($handle, ['cookie-banner'], true)) return $tag;
    return str_replace(' src=', ' defer src=', $tag);
}, 10, 2);

GSAP, animacje, magnetic cursor — wszystko ładuje się dopiero po pierwszym renderze. Lighthouse mierzy First Contentful Paint na początku — później załadowany JS go nie obciąża.

7. Brotli + Gzip + HTTP/2

Server-side. Domyślnie w Apache trzeba włączyć mod_brotli i mod_deflate. W Coolify (Traefik) jest to już domyślne.

HTTP/2 multiplexuje requesty na jednym połączeniu. Zero round-trip dla każdego CSS/JS/IMG. To 200-500ms zysku na stronie z 30+ assetami.

Czego NIE rób

  • Plugin cache — często konflikty z custom kodem, wstrzykuje JS który psuje Twój flow
  • Image optimization plugin — WP Smush, ShortPixel itp. zwykle robią WORSE quality + WORSE size niż PHP+Imagick na hooku add_attachment
  • JS minifier z pluginu — używaj build step (esbuild, swc), nie runtime’a
  • Lazy load wszystko — krytyczne above-fold obrazki MUSZĄ ładować się normalnie. Lazy load + LCP = paradoks (LCP czeka na lazy load image)

Realne liczby z produkcji

Strona JTM Development (custom motyw, harvester, plan osiedla SVG, 20 lokali z meta + zdjęciami):

  • Performance: 96 mobile / 100 desktop
  • Accessibility: 100
  • Best Practices: 98
  • SEO: 100
  • LCP: 1.4s na 4G mobile
  • CLS: 0.02
  • JS bundle: 47KB (gzipped) total

Bez WP Rocket. Bez Smush. Bez Cloudflare. Tylko custom kod + parę godzin czasu na rzeczy z tej listy.

Spodobało się? Podziel się.

Zaczynamy?

Odpowiem do końca dnia roboczego.