Skip to content

Wszystko o WordPressie, tworzeniu stron — i nie tylko

⚡ Jak pobrać czcionki internetowe bez utraty szybkości i przyspieszyć wyświetlanie tekstu

⚡ Jak pobrać czcionki internetowe bez utraty szybkości i przyspieszyć wyświetlanie tekstu

Kiedy strona ładuje się 3 sekundy, a potem jeszcze przez sekundę przestawia cały tekst, odwiedzający odchodzi. Nie do konkurencji, tylko po prostu zamyka kartę. Problem prawie zawsze leży w jednym: web fonty zostały załadowane bez uwzględnienia wydajności.

Według danych HTTP Archive za 2025 rok około 84% stron używa niestandardowych web fontów, a mediana stron wykonuje 5 zapytań do plików fontów o łącznej objętości blisko 400 KB. Przy słabym połączeniu to 2-3 sekundy blokowania renderowania, kiedy użytkownik widzi pusty ekran. A Google uwzględnia Cumulative Layout Shift spowodowany podmianą fontu w Core Web Vitals.

Cztery poniższe kroki to nie teoria. To praktyczne minimum, które rozwiązuje zdecydowaną większość problemów z wydajnością web fontów. Każdy krok zajmuje od 5 do 15 minut.

💡 Szybki przegląd:

  • Zdecyduj się na formaty: woff2 jako podstawowy i woff jako fallback, to wystarcza dla wszystkich nowoczesnych przeglądarek.
  • Dodaj preload dla krytycznych fontów, aby przeglądarka nie czekała na CSS, tylko od razu zaczynała ładowanie.
  • Sprawdź font-face: local(), prawidłową kolejność src, unicode-range dla alfabetu łacińskiego.
  • Skonfiguruj font-display: swap, a odwiedzający widzi tekst natychmiast, nawet gdy font wciąż się ładuje.

Krok 1: Używaj woff2 i woff, reszta jest zbędna

Formatów web fontów jest wiele: EOT, TTF, OTF, SVG. Ale w 2026 roku realnie potrzebne są tylko dwa.

woff2, nowoczesny standard. Pliki są o 30% mniejsze niż woff przy tej samej jakości, ponieważ używają kompresji brotli zamiast gzip. Wsparcie przeglądarek obejmuje wszystkie przeglądarki evergreen, w tym mobilne Safari i Samsung Internet. Globalnie to 98%+ użytkowników.

woff, fallback dla niewielkiej części starych przeglądarek (Safari na iOS 11 i starszych, rzadkie środowiska korporacyjne). Również jest skompresowany, działa wszędzie od IE9+. Trzymaj go jako ostatni w src, a przeglądarka weźmie woff2, jeśli może, w przeciwnym razie cofnie się do woff.

EOT (Internet Explorer 8 i starsze) oraz TTF (surowy format, bez kompresji) w 2026 roku nie używaj. Udział takich przeglądarek to błąd statystyczny, a każdy dodatkowy format w src zwiększa CSS i dezorientuje przeglądarkę.

Jeśli masz pliki w TTF lub OTF, przekonwertuj je przez generator online. Transfonter tworzy woff2 i woff w jednej operacji, pokazując podgląd glifów i końcową objętość. Alternatywa to Font Squirrel Webfont Generator.

Krok 2: Wstępnie załaduj krytyczne fonty przez preload

Przeglądarka dowiaduje się o foncie z CSS, a CSS czyta po HTML. Zanim do niego dotrze, mija 500-800 ms na przeciętnym połączeniu. Preload skraca to opóźnienie do zera: przeglądarka zaczyna ładować font, gdy tylko napotka tag w <head>, nie czekając na CSS.

Minimalny działający tag:

1<link rel="preload" as="font"
2 href="/fonts/open-sans.woff2"
3 type="font/woff2"
4 crossorigin="anonymous">

Kluczowe jest crossorigin="anonymous". Bez tego przeglądarka zignoruje wstępnie załadowany font i załaduje go ponownie. Powodem jest to, że fonty są pobierane anonimowo (CORS), a preload bez crossorigin wykonuje zwykłe zapytanie; przeglądarka uznaje to za różne zasoby i ich nie dopasowuje.

Co wstępnie ładować. Nie każdy font na stronie. Tylko ten, który jest używany do głównego tekstu w widocznej części strony (above the fold): nagłówek, body, nawigacja. Reszta poczeka. Wstępne ładowanie 4-5 plików daje malejący zwrot i zabiera pasmo krytycznej treści.

Ważny niuans z Google Fonts i CDN. Jeśli bierzesz fonty z Google Fonts, pliki są okresowo aktualizowane, a link preload do starej wersji spowoduje podwójne załadowanie (stara + nowa). Zamiast preload dla fontów z CDN użyj <link rel="preconnect"> do domeny fontów, to przyspieszy handshake bez ryzyka rozbieżności wersji:

1<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

Prefetch dla drugorzędnych fontów. rel="prefetch" informuje przeglądarkę: „ten zasób będzie potrzebny później, załaduj, gdy główne będą gotowe". Pasuje do fontów na wewnętrznych stronach lub do fontów ikon w stopce. Priorytet jest niski, nie zabiera pasma.

Nowoczesny przewodnik po priorytetyzacji zasobów znajduje się w dokumentacji web.dev.

Krok 3: Przygotuj @font-face bez błędów

Na pierwszy rzut oka @font-face jest prosty. W praktyce ma cztery newralgiczne punkty, a każdy wpływa na szybkość.

Przykład poprawnej deklaracji:

1@font-face {
2 font-family: 'Open Sans';
3 font-weight: 400;
4 font-style: normal;
5 font-display: swap;
6 unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC,
7 U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074,
8 U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
9 U+FEFF, U+FFFD;
10 src: local('Open Sans'),
11 url('/fonts/open-sans.woff2') format('woff2'),
12 url('/fonts/open-sans.woff') format('woff');
13}

Analiza punkt po punkcie:

local(): jako pierwszy w src. Jeśli użytkownik ma font już zainstalowany w systemie (Roboto na Androidzie, Segoe UI na Windows, San Francisco na macOS), przeglądarka weźmie lokalną kopię i nie załaduje ani jednego bajta. Zawsze umieszczaj local() jako pierwszą linię w src. Nazwę bierz z samego pliku fontu: local('Open Sans') oraz local('Roboto Regular').

Kolejność formatów. Przeglądarka przechodzi przez src od lewej do prawej i bierze pierwszy format, który rozumie. Dlatego: local()woff2woff. Żadnych EOT/TTF/SVG na końcu, chyba że masz specyficzną grupę odbiorców ze starymi przeglądarkami, i wtedy idą one PO woff (nie przed).

unicode-range, ładujemy tylko potrzebne glify. Dla alfabetu łacińskiego wystarczy zakres U+0000-00FF (Basic Latin + Latin-1 Supplement). To ~250 glifów wobec kilku tysięcy w pełnym zestawie. Rzeczywista objętość pliku spada 3-5 razy. Nie przeciążaj zakresu, każdy dodatkowy unicode-block dodaje glify, których nikt nie zobaczy. Dla stron z cyrylicą dodaj U+0400-04FF.

Kolejność bloków @font-face. Jeśli masz kilka odmian (regular, bold, italic), zwykłą odmianę (font-weight: 400) umieszczaj jako pierwszą, przeglądarka zacznie ładować właśnie ją.

Krok 4: Włącz font-display: swap i pożegnaj się z FOIT

Flash of Invisible Text (FOIT) to sytuacja, gdy przeglądarka ukrywa tekst na 3 sekundy, czekając na font. Użytkownik widzi pustą stronę. Flash of Unstyled Text (FOUT) to tekst od razu widoczny fontem systemowym, a potem zastępowany niestandardowym. To drugie jest zawsze lepsze od pierwszego.

font-display: swap w @font-face robi dokładnie to: tekst jest renderowany natychmiast fontem systemowym, a gdy niestandardowy się załaduje, jest podmieniany. Idealne dla głównego tekstu.

Inne wartości i kiedy je stosować:

  • swap, dla tekstu body. Tekst widoczny od razu, podmiana płynna.
  • optional, dla fontów dekoracyjnych i ikon. Przeglądarka decyduje, czy w ogóle warto ładować font: przy słabym połączeniu zrezygnuje i zostawi systemowy. Okres oczekiwania to 100 ms.
  • block, krótkie blokowanie (zazwyczaj 3 sekundy), potem tekst jest widoczny, font podmieni się, gdy się załaduje. Prawie nieużywane.
  • fallback, kompromis: krótkie blokowanie, potem tekst widoczny, font podmieni się, jeśli zdąży się szybko załadować.

W praktyce dla tekstu body ustawiaj swap, dla fontów ikon i dekoracji optional. To wystarcza.

Zachowanie przeglądarek bez font-display. Jeśli nie wskażesz niczego, Chrome ukrywa tekst do 3 sekund, Firefox do 3 sekund, Safari w nieskończoność, Edge od razu pokazuje systemowy. Z font-display: swap to zachowanie jest ujednolicone, a wynik przewidywalny.

Jak sprawdzić wynik

Sprawdź swoją stronę przed i po na web.dev/measure, Lighthouse pokaże „Ensure text remains visible during webfont load" jako osobną linię. Jeśli audyt jest czerwony, Twój font-display nie działa lub go brakuje.

Do ręcznego sprawdzenia: otwórz DevTools → Network, ustaw throttling „Slow 3G" i odśwież stronę. Tekst powinien pojawić się fontem systemowym natychmiast, a nie po 3 sekundach pustego ekranu.

Na zrzutach ekranu poniżej różnica między standardowym podejściem a zoptymalizowanym (test na Slow 3G):

Standardowe ładowanie czcionek z blokowaniem tekstu

Typowo: tekst ukryty, dopóki font się nie załaduje

Zoptymalizowane ładowanie z natychmiastowym wyświetlaniem tekstu

Zoptymalizowane zachowanie: tekst widoczny od razu fontem systemowym

Widać gołym okiem: na pierwszym zrzucie biały ekran, na drugim treść dostępna natychmiast.

Na konferencji performance.now() 2024 Mandy Michael analizuje zaawansowane strategie, inkrementalny unicode-range, font slicing i pracę z fontami zmiennymi. Dla tych, którzy chcą pójść dalej niż cztery podstawowe kroki.

⁉️🤔 Często zadawane pytania

Po co jest woff, skoro woff2 jest wszędzie wspierany?

Użytkownicy starych iOS Safari (iOS 11 i starsze) oraz rzadkich środowisk korporacyjnych z zablokowanymi przeglądarkami, które pozostały, nie obsługują woff2. Bez fallbacku woff ci użytkownicy zobaczą font systemowy zamiast Państwa fontu. Woff dodaje 15-20 KB do zestawu, to niewielka cena za pokrycie szczątkowej części.

Czy można używać Google Fonts i nie przejmować się?

Można i dla większości stron jest to optymalna droga. Google Fonts automatycznie serwuje woff2 nowoczesnym przeglądarkom, używa CDN z geodystrybucją i obsługuje display=swap parametrem w URL. Minusy: zależność od zewnętrznego CDN (kwestie prywatności, GDPR), brak możliwości zarządzania unicode-range i lokalną instalacją fontów. Jeśli prywatność i kontrola są ważne, self-host fontów.

Jak sprawdzić, czy fonty realnie spowalniają stronę?

Lighthouse (zakładka Audits w Chrome DevTools) pokaże audyt „Ensure text remains visible during webfont load". WebPageTest da waterfall z timingiem każdego zapytania o font. Jeśli fonty startują później niż pierwszy CSS, preload nie jest skonfigurowany. Jeśli przesunięcie układu jest większe niż 0.1, font powoduje Cumulative Layout Shift i Google zalicza to do Core Web Vitals.

font-display: swap psuje design, tekst „skacze" przy podmianie?

Tak, to znany minus swap. Należy walczyć z tym dwoma technikami. Pierwsza: ustaw dla tekstu font-size i line-height takie same jak w systemowym foncie fallback, różnica w metrykach będzie minimalna. Druga: użyj Font Style Matcher lub modułu size-adjust w @font-face (dostępnego w nowoczesnych przeglądarkach), aby dopasować metryki niestandardowego fontu do systemowego. Po dopasowaniu CLS będzie zerowy.

Czy trzeba wstępnie ładować wszystkie fonty na stronie?

Nie. Wstępnie ładuj tylko fonty krytyczne, te, które tworzą tekst widocznej części strony (pierwsze 1-2 ekrany). Resztę ładuj standardowo przez CSS. Wstępne ładowanie 5+ fontów zapycha pasmo i opóźnia ważniejsze zasoby w kolejce. W praktyce 1-2 linki preload pokrywają zdecydowaną większość scenariuszy.

Czy warto się tym przejmować: cztery kroki, cztery minuty

Konfiguracja web fontów to nie projekt na tydzień. Konwersja do woff2, poprawka @font-face, preload i font-display: swap to 20-30 minut pracy, nawet jeśli nigdy Pan/Pani tego nie robił/a.

Korzyść jest mierzalna: tekst staje się widoczny 1.5-2.5 sekundy wcześniej na Slow 3G. Core Web Vitals nie karzą za przesunięcie układu. A użytkownik nie odchodzi, patrząc na biały ekran.

Proszę zacząć od jednego fontu, głównego tekstowego. Wykonać cztery kroki. Sprawdzić Lighthouse przed i po. Różnica w liczbach przekona lepiej niż jakiekolwiek argumenty.