Wasz wybór

Powiązane artykuły

Optymalizacja fontów dla SEO i wydajności

Czasy ładowania strony mają bezpośredni wpływ na pozycje w Google — to fakt, który potwierdzają zarówno algorytm Core Web Vitals, jak i dane z tysięcy audytów. Fonty webowe potrafią być jednym z największych hamulców wydajności, szczególnie gdy ładują się synchronicznie i blokują renderowanie strony. Optymalizacja fontów to jeden z tych obszarów, gdzie stosunkowo niewielka zmiana w kodzie przekłada się na mierzalne skrócenie czasu wyświetlania treści.

W tym poradniku przechodzimy przez całą ścieżkę — od wyboru właściwego formatu pliku, przez preload i font-display, aż po techniki zaawansowane jak subsetting czy variable fonts. Każdy krok ma konkretne uzasadnienie i mierzalny efekt.

Formaty fontów i dlaczego woff2 wygrywa dziś ze wszystkim

Przez lata ekosystem fontów webowych wyglądał jak muzeum formatów — TTF, OTF, EOT, SVG, WOFF i WOFF2 funkcjonowały równolegle, a deweloperzy kopiowali ogromne bloki @font-face z czterema deklaracjami src. Dziś sytuacja jest prostsza.

Format woff2 korzysta z kompresji Brotli, co daje rozmiary plików o 30-50% mniejsze niż WOFF i nawet dwukrotnie mniejsze niż surowe TTF lub OTF. Przeglądarka Chrome obsługuje go od 2015 roku, Firefox od 2014, Safari od 2016. W 2024 roku udział przeglądarek obsługujących woff2 przekracza 97% globalnego ruchu webowego, więc dołączanie starszych formatów jako fallback jest w większości projektów zbędne.

Praktyczna rekomendacja: deklaruj @font-face z jednym źródłem woff2. Jeśli projekt musi obsługiwać naprawdę starą bazę użytkowników (np. aplikacja korporacyjna na zamrożonych wersjach IE), dodaj WOFF jako fallback — ale nie TTF, który jest kilkukrotnie cięższy.

`css @font-face{ font-display:swap; font-family: 'Nazwa’; src: url(’font.woff2′) format(’woff2′); font-weight: 400; font-style: normal; } `

Warto przy tym zadbać o poprawne nagłówki cache po stronie serwera. Fonty zmieniają się rzadko, więc Cache-Control: max-age=31536000, immutable z wersjonowaniem nazwy pliku to wzorzec, który eliminuje zbędne requesty przy kolejnych wizytach użytkownika.

Preload — kiedy i jak informować przeglądarkę o fontach

Przeglądarka odkrywa fonty późno. Parser HTML czyta plik, pobiera CSS, przetwarza reguły i dopiero wtedy trafia na deklarację @font-face. W typowym scenariuszu font nie zaczyna się pobierać wcześniej niż po 200-400 ms od inicjacji ładowania strony — a nierzadko później.

Dyrektywa preload rozwiązuje ten problem, informując przeglądarkę jeszcze podczas parsowania , że konkretny plik będzie potrzebny:

`html `

Atrybut crossorigin jest wymagany zawsze — nawet gdy font hostowany jest na tej samej domenie. Bez niego przeglądarka pobierze plik dwukrotnie.

Ile fontów preloadować i jak unikać przeładowania przeglądarki

Preload ma sens tylko dla fontów krytycznych — tych, które trafiają na teksty widoczne „above the fold” bez przewijania. Wczytywanie z wyprzedzeniem czterech lub pięciu różnych krojów jest kontrproduktywne: zwiększa konkurencję o przepustowość łącza i może opóźniać ładowanie obrazów czy skryptów wyżej w priorytetach.

Bezpieczna reguła: preloaduj maksymalnie 2-3 pliki fontów na stronę. W praktyce często wystarczy jeden — główna waga regularna (400) dla tekstu podstawowego. Kursywa i wagi nagłówkowe mogą ładować się bez preload, bo użytkownik zaczyna czytać od treści, nie od nagłówka.

Fonty z Google Fonts i CDN — jak je obsługiwać lokalnie

Zewnętrzne CDN fontów generują dodatkowe połączenia DNS, handshake TLS i request do zewnętrznego serwera. Google Fonts to zwykle 50-150 ms dodatkowego opóźnienia już przy pierwszej wizycie. Dla Core Web Vitals, a konkretnie dla LCP (Largest Contentful Paint), każde 100 ms ma znaczenie.

Najskuteczniejsze rozwiązanie to self-hosting: pobranie plików woff2 i osadzenie ich bezpośrednio na własnym serwerze. Eliminuje zewnętrzne zależności, daje pełną kontrolę nad cachingiem i pozwala stosować preload bez ograniczeń cross-origin policy.

Font display swap i zarządzanie FOIT/FOUT

Gdy przeglądarka nie ma jeszcze pobranego fontu, staje przed dylematem: pokazać tekst systemowym fontem zastępczym (FOUT — Flash of Unstyled Text) czy czekać na font webowy i nie pokazywać nic (FOIT — Flash of Invisible Text). Domyślne zachowanie różni się między przeglądarkami i zwykle nie jest tym, czego chcemy.

Właściwość font-display daje nam bezpośrednią kontrolę nad tym procesem. Dostępne wartości i ich praktyczne znaczenie:

  • swap — przeglądarka natychmiast renderuje tekst fontem systemowym, a gdy font webowy się załaduje, zamienia go. Tekst zawsze widoczny, krótki „przeskok” wizualny przy zamianie.
  • block — krótki okres niewidoczności tekstu (do 3 sekund), potem fallback. Niekorzystne dla LCP, bo treść jest niewidoczna.
  • fallback — bardzo krótki blok (100 ms), potem fallback; jeśli font nie dotrze w ciągu ~3 sekund, przeglądarka rezygnuje ze zmiany. Dobry kompromis.
  • optional — 100 ms bloku, potem decyzja oparta na warunkach sieciowych; font może zostać pominięty całkowicie przy wolnym połączeniu.
  • auto — zachowanie domyślne dla danej przeglądarki, zwykle zbliżone do block.

Dla większości projektów font-display: swap to właściwy wybór — tekst jest zawsze widoczny, co bezpośrednio poprawia metrykę FCP (First Contentful Paint). Jeśli estetyka zamiany fontów jest problemem (np. przy bardzo różniących się metrykach fallback i webowego fontu), fallback daje lepszy balans.

`css @font-face{ font-family: 'Nazwa’; src: url(’font.woff2′) format(’woff2′); font-display: swap; } `

Zmiana jednego atrybutu często przynosi skrócenie FCP o 0.3-0.8 sekundy w testach Lighthouse — bez żadnych innych modyfikacji kodu.

Subsetting i variable fonts — zaawansowana redukcja rozmiaru

Standardowy plik fontu zawiera glify dla wszystkich znaków obsługiwanych przez krój — łacina, cyrylica, greka, symbole, znaki specjalne. Dla strony wyłącznie po polsku 60-70% tych danych nigdy nie zostanie użyta, a jednak trafia do przeglądarki użytkownika.

Subsetting — font dopasowany do faktycznie używanych znaków

Subsetting polega na wygenerowaniu pliku zawierającego tylko te glify, których faktycznie używamy. Dla projektu z polskojęzyczną treścią potrzebujemy: znaki ASCII, polskie diakrytyki (ą ć ę ł ń ó ś ź ż i ich wersje wielkie), ewentualnie cyfry i podstawową interpunkcję.

Narzędzia takie jak pyftsubset (część pakietu fonttools) pozwalają wygenerować subset z linii poleceń. Google Fonts przy użyciu parametru subset=latin-ext robi podobną operację po swojej stronie. Efekty są znaczące: font o wadze 120 kB po subsetingu dla polskiego Latin Extended może ważyć 18-25 kB.

Przy subsetingu trzeba uważać na jedną pułapkę: jeśli treść strony jest dynamiczna lub wielojęzyczna, zbyt agresywne ograniczenie znaków spowoduje że część tekstu wyrenderuje się fontem fallback. Bezpieczne minimum to zawsze pełny zakres Latin + Latin Extended.

Variable fonts — jeden plik zamiast pięciu

Tradycyjny workflow wymagał osobnego pliku dla każdej kombinacji wagi i stylu: Regular, Bold, Italic, Bold Italic, Light — pięć plików, pięć requestów HTTP lub jeden połączony plik ale o sumie rozmiarów wszystkich wariantów.

Variable fonts rozwiązują ten problem za pomocą jednego pliku zawierającego osie zmienności — oś wagi (wght), szerokości (wdth), ukosowania i innych parametrów zdefiniowanych przez projektanta kroju. Zamiast font-weight: 400 i font-weight: 700 jako osobnych plików, przeglądarka interpoluje dowolną wartość z jednego zasobu.

Rozmiar takiego pliku jest większy niż jeden wariant, ale mniejszy niż suma wszystkich wariantów. Przy projekcie używającym 3-4 wag fontu variable fonts dają oszczędność rzędu 40-60% łącznej wagi zasobów typograficznych.

`css @font-face{ font-family: 'NazwaVariable’; src: url(’font-variable.woff2′) format(’woff2-variations’); font-weight: 100 900; font-display: swap; } `

Obsługa przeglądarek dla variable fonts przekracza 95% w 2024 roku, więc w nowych projektach nie ma uzasadnienia dla utrzymywania osobnych plików statycznych wag.

Audyt fontów w Lighthouse i Core Web Vitals — co mierzyć i jak interpretować wyniki

Optymalizacja bez pomiaru to zgadywanie. W praktyce audyt fontów zaczynamy od raportu Lighthouse w Chrome DevTools — zakładka Performance, audyt dla urządzeń mobilnych (warunki sieciowe 3G odzwierciedlają realne doświadczenie sporej części użytkowników).

Kluczowe metryki, które fonty bezpośrednio wpływają:

  • FCP (First Contentful Paint) — czas do pierwszego wyrenderowania tekstu lub obrazu. Font blokujący renderowanie lub font-display: block bezpośrednio wydłużają tę metrykę.
  • LCP (Largest Contentful Paint) — czas do wyrenderowania największego elementu w viewport. Jeśli LCP to blok tekstu (co zdarza się często przy hero sections z nagłówkiem), niepobrany font opóźnia tę metrykę.
  • CLS (Cumulative Layout Shift) — skumulowane przesunięcia layoutu. Zamiana fontu fallback na webowy może powodować przeskok tekstu, jeśli metryki obu krojów (wysokość linii, spacing) znacznie się różnią.

Technikę „size-adjust” i ascent-override w CSS można używać do kalibracji fontu fallback tak, żeby metryki jak najbardziej zbliżały się do docelowego kroju. Redukuje to CLS przy przełączeniu fontów nawet przy aktywnym font-display: swap.

W zakładce Network DevTools filtruj po typie „Font” i sprawdzaj moment inicjacji requestu. Jeśli request startuje po 500 ms od nawigacji, preload prawdopodobnie nie jest skonfigurowany lub nie działa poprawnie. Dobrze skonfigurowany preload przesuwa start requestu fontów na pierwsze 100-200 ms.

Regularne audyty po każdej zmianie typografii w projekcie to jedyny sposób, żeby mieć pewność, że kolejna aktualizacja designu nie cofnęła osiągniętych wyników. Zestawienie wyników przed i po każdej optymalizacji warto trzymać w formie tabeli z datą i wartościami FCP/LCP/CLS — widoczny progres motywuje zespół i dokumentuje faktyczny wpływ zmian technicznych na metryki SEO.

Miłosz Fryzel
Miłosz Fryzel
Senior SEO Specialist Miłosz swobodnie porusza się po wszystkich obszarach pozycjonowania — od technicznego SEO, przez content, po link building. Jego analityczne podejście sprawia, że nawet drobne optymalizacje przekładają się na wymierne efekty widoczności.
Popularne