Gdy ktoś pyta mnie, WOFF2 czy TTF, odpowiadam krótko: na stronę wysyłaj WOFF2, a plik TTF lub OTF zachowaj jako źródło do przyszłych zmian. We wrześniu 2026 przekonwertowałem 13 fontów z macOS i każdy plik WOFF2 wyszedł mniejszy od oryginału o 42,6–70,8%, a tekst w przeglądarce wyglądał identycznie (pakiet badania). Mniejszy plik to mniej danych przy pierwszej wizycie, a to, czy tekst pojawi się szybciej, i tak trzeba sprawdzić na swojej stronie.
Niżej pokazuję, kiedy konwersja ma sens, jak ją zrobić bez utraty znaków, jak dodać WOFF2 do CSS i jak ocenić efekt w DevTools. Jeden wynik, 94,5%, musiałem po drodze odrzucić i też wyjaśniam dlaczego.
WOFF2 i TTF: czym różnią się pliki fontów
WOFF2 to format pakowania fontu do przesyłania w sieci. Według specyfikacji W3C WOFF 2.0 bierze te same dane co TTF, przekształca wybrane tabele i kompresuje całość algorytmem Brotli. Krótką definicję znajdziesz też w słowniku pod hasłem WOFF2.
Oba formaty przeglądarka wczyta przez @font-face, a według caniuse WOFF2 obsługuje każda popularna przeglądarka. Plik .ttf może mieć kontury TrueType albo CFF i WOFF2 pakuje oba rodzaje, co jeszcze wróci przy porównaniu z samym Brotli.
Co zyskuje odwiedzający twoją stronę
Przeglądarka musi pobrać czcionkę albo odczytać ją z pamięci podręcznej, więc duży plik TTF oznacza więcej danych do pobrania przy pierwszym otwarciu strony. Różnica rośnie na wolnym łączu i wtedy, gdy strona używa kilku odmian tej samej czcionki.
Dobrym przykładem jest Georgia z mojego testu. Oryginał zajmował 379 588 bajtów, a plik WOFF2 tylko 110 840, czyli o 268 748 bajtów (ok. 269 kB) mniej w jednym pliku. Nie oznacza to, że strona załaduje się o 70,8% szybciej, bo mierzyłem rozmiar plików, a nie czas wczytywania strony.
Odwiedzający zauważy zmianę tylko wtedy, gdy font blokował pierwsze wyświetlenie tekstu. Jeśli plik jest już w cache albo stronę spowalnia serwer czy ciężki skrypt, mniejsza czcionka niewiele zmieni. Dlatego traktuję WOFF2 jako sposób na ograniczenie przesyłanych danych, a poprawę wskaźników wydajności sprawdzam osobno.
Sprawdź, czy twoja strona w ogóle wysyła fonty
Zanim zaczniesz konwersję, otwórz stronę w przeglądarce, uruchom narzędzia deweloperskie i przejdź do zakładki Network z filtrem Font. Zobaczysz tam formaty, rozmiary i liczbę odmian, które przeglądarka faktycznie pobiera.
Jeśli strona już wysyła WOFF2, ponowna konwersja tego samego pliku nie powinna być pierwszym zadaniem. Przy czcionkach systemowych przeglądarka w ogóle nie pobiera osobnych fontów, więc nie ma czego zmniejszać.
Gdy widzisz kilka dużych plików TTF lub OTF, ja bym spróbował WOFF2 i przy okazji sprawdził, czy strona naprawdę potrzebuje wszystkich grubości i wariantów, bo każdy dodatkowy plik to kolejne pobieranie. Pamiętaj też o licencji, bo nie każdą czcionkę wolno samodzielnie konwertować i udostępniać na stronie.
Jak przekonwertować TTF lub OTF na WOFF2 bez utraty znaków
Zachowaj oryginał, a potem przygotuj wersję WOFF2, na przykład w naszym konwerterze fontów albo w narzędziu, które już znasz. Po konwersji porównuj tę samą czcionkę i tę samą odmianę, bo inaczej porównujesz pliki o różnej zawartości.
Konwersja do WOFF2, usunięcie nieużywanych znaków i wyrzucenie hintingu to trzy różne operacje, a narzędzie może wykonać wszystkie naraz i pokazać jedną liczbę. Tak działa też nasz konwerter, który po wybraniu podzbioru znaków przed kompresją usuwa również hinting. Sam efekt formatu zobaczysz dopiero przy konwersji bez podzbioru.
Podzbiór znaków zaczynaj od tego, czego wymaga treść, a rozmiar pliku sprawdzaj dopiero potem. Poza alfabetem cena potrzebuje znaku euro, cytat cudzysłowów drukarskich, a godziny otwarcia półpauzy, i wszystko to wyłapuje jedno zdanie testowe:
„Zażółć gęślą jaźń” — 129 €; dostępność: 9–17…
Przepuściłem je przez zakresy naszego presetu latin-ext. Każda polska litera przeszła, ale tych ośmiu znaków w nim brakuje:
Znak | Punkt kodowy | W |
|---|---|---|
| U+20AC | brak |
półpauza | U+2013 | brak |
pauza | U+2014 | brak |
| U+201E, U+201D | brak |
| U+2019 | brak |
| U+2026 | brak |
łączący akcent ostry | U+0301 | brak |
Imiona w formularzach, nowe wpisy w CMS i tłumaczenia przyniosą znaki spoza dzisiejszych tekstów, więc tam zostaw szersze pokrycie i działający font zastępczy. Podzbiór pod konkretny tekst ma sens dla napisów, które się nie zmieniają, na przykład logo albo nagłówka kampanii.
Deskryptor CSS unicode-range mówi przeglądarce, dla których znaków użyć danego pliku. Według MDN wystarczy jeden znak z zakresu, żeby strona pobrała cały font, a szeroka deklaracja w CSS nie przywróci znaku usuniętego podczas eksportu.
Georgia w TTF i WOFF2 wygląda identycznie
Sprawdziłem Georgię w obu formatach w Chrome na macOS, mierząc szerokość napisu w DOM i porównując piksele na canvasie przy podwójnej gęstości ekranu:
28px „Zażółć gęślą jaźń” — 129 €; 9–17…
TTF 429,805 px WOFF2 429,805 px różnica 0,000 px różniące się piksele: 0
16px Hamburgefonstiv 0123456789 fi fl ffi — AV To Wa
TTF 328,633 px WOFF2 328,633 px różnica 0,000 px różniące się piksele: 0
Piksele liczę, bo tekst o tej samej szerokości wciąż może wyglądać inaczej. Dwa napisy w jednej przeglądarce to wąskie sprawdzenie, co surowe wyniki mówią wprost, więc powtórz je na swoich fontach, zwłaszcza dla pogrubienia, kursywy i osi fontów zmiennych.
Jak dodać WOFF2 do CSS
Gdy masz już właściwy plik, wskaż go jedną deklaracją @font-face z jawną strategią ładowania. Przykład dotyczy jednej odmiany o grubości 400, a ścieżkę zastąp własnym adresem:
@font-face {
font-family: "Example Sans";
src: url("/fonts/example-regular.woff2") format("woff2");
font-style: normal;
font-weight: 400;
font-display: swap;
}
body {
font-family: "Example Sans", system-ui, sans-serif;
}
Jeśli starsze środowisko wymaga WOFF, wpisz go po WOFF2 na tej samej liście src. Według CSS Fonts Level 4 przeglądarka używa pierwszego źródła, które zdoła wczytać, więc tam, gdzie WOFF2 działa, WOFF nie jest pobierany.
Deskryptor font-display decyduje, co dzieje się z tekstem, zanim font dotrze. Tabela streszcza opis wartości w MDN:
Wartość | Co widzi odwiedzający |
|---|---|
| font zastępczy niemal od razu, font webowy podmienia go później |
| krótkie okno na podmianę, potem zostaje font zastępczy |
| bez późniejszej podmiany, wizyta może zostać przy foncie zastępczym |
| dłuższy okres niewidocznego tekstu przed fontem zastępczym |
Przy swap podmiana może zmienić łamanie wierszy, gdy metryki fontów się różnią, a font zastępczy dopasujesz przez size-adjust i nadpisania metryk policzone dla własnej pary fontów.
Preload dodaj tylko dla odmian potrzebnych na pierwszym ekranie, bo zbyt wiele zasobów z wysokim priorytetem konkuruje z obrazami i innymi ważnymi plikami:
<link rel="preload" href="/fonts/example-regular.woff2" as="font" type="font/woff2" crossorigin>
Użyj tego samego URL-a co w CSS i zachowaj crossorigin nawet dla plików z tej samej domeny, jak opisuje MDN o preload. Serwuj plik z nagłówkiem Content-Type: font/woff2, a adresowi z hashem treści daj Cache-Control: public, max-age=31536000, immutable, ale tylko wtedy, gdy zmieniony plik zawsze dostaje nowy URL.
Jak sprawdzić efekt wdrożenia WOFF2 w DevTools
Po wdrożeniu porównaj poprzednią wersję fontu z WOFF2 w tej samej zakładce Network, w czterech krokach:
- Zostaw tylko fonty i przeładuj stronę z wyłączoną pamięcią podręczną, a potem sprawdź URL, status, typ MIME i przesłane bajty.
- Powtórz to z włączoną pamięcią podręczną i oceniaj powroty na stronę osobno od pierwszych wizyt.
- Sprawdź, który font narysował tekst, bo font zastępczy po cichu łata luki, zwłaszcza w nagłówkach, przyciskach, polach formularzy i cenach.
- Zmieniaj jedną rzecz naraz i trzymaj osobno format, podzbiór, strategię ładowania i preload, dopóki nie wiesz, co dała każda zmiana.
Jeśli chcesz ocenić szybkość całej strony, zmierz ją przed wdrożeniem i po nim w porównywalnych warunkach, bo mój test nie mierzył LCP, CLS ani zużycia energii. Jak czytam takie pomiary i dlaczego dane laboratoryjne różnią się od danych z Chrome, pokazuję w porównaniu Lighthouse z CrUX.
WOFF2 zmniejszył 13 fontów o 42,6–70,8%
Do testu wziąłem trzynaście fontów z systemowego katalogu macOS i przekonwertowałem je w fontTools bez podzbioru znaków, usuwania hintingu i zmian osi fontów zmiennych, bo chciałem zobaczyć sam wpływ formatu. WOFF2 zmniejszył je o 42,6–70,8%, z medianą 54,7%, a wielkość pliku nie przewidywała oszczędności.
Najwięcej straciła Georgia, najmniej Noto Sans Canadian Aboriginal, a malutki Noto Sans Lycian schudł prawie tyle samo co Arial Unicode, który ma 23 MB. Dlatego najrozsądniej przetestować własny zestaw fontów, a pełną tabelę z bajtami zostawiłem na końcu artykułu.
Wynik 94,5% musiałem odrzucić
W jednej z pierwszych prób zobaczyłem redukcję aż o 94,5%. Plik Athelas.ttc zajmował około 2,3 MB, a powstały WOFF2 około 127 KB, więc wyglądało to na wyjątkowo skuteczną kompresję.
Kiedy zajrzałem do środka, okazało się, że oryginał jest kolekcją czterech odmian czcionki, a plik wynikowy zawiera tylko jedną. Porównywałem więc pliki o różnej zawartości i usunąłem tę próbę z zestawienia.
Od tamtej pory sprawdzam nie tylko liczbę z konwertera, ale też to, co znalazło się w pliku, bo duża oszczędność niewiele daje, jeśli po drodze znikną potrzebne odmiany albo znaki.
WOFF2 wygrywa z samym Brotli tylko przy konturach TrueType
WOFF2 używa Brotli, więc chciałem sprawdzić, czy daje coś ponad zwykłe spakowanie oryginału. Każdy oryginał skompresowałem osobno samym Brotli na najwyższym poziomie jakości i porównałem z plikiem WOFF2.
Przy konturach TrueType WOFF2 wygrał w medianie o 11,7%, a przy CFF tylko o 0,5%. Według specyfikacji W3C WOFF2 przekształca dane glifów TrueType, między innymi tabelę glyf, a dane CFF zostawia bez zmian, bo są już zwarte. Przy dwóch z czterech fontów CFF samo Brotli dało nawet minimalnie mniejszy plik.
Mój jedyny font zmienny, SF Pro z konturami TrueType, też wylądował blisko zera, jak grupa CFF, ale przy jednej obserwacji traktuję to jako trop do sprawdzenia. Domyślnym wyborem WOFF2 zostaje i tak, bo przychodzi skompresowany bez konfiguracji serwera.
To porównanie zrobiłem offline, a rozmiar pliku i transfer HTTP to dwie różne liczby. Serwer może skompresować odpowiedź z plikiem TTF przez Content-Encoding, a WOFF2 ma kompresję w paczce, więc przesłane bajty zawsze sprawdzaj w DevTools.
Co wybrałbym na własnej stronie
Na nowej stronie z własną czcionką od razu zacząłbym od WOFF2. Na starszej stronie z TTF lub OTF przekonwertowałbym jeden plik, sprawdził jego znaki i porównał działanie w przeglądarce, a oryginał zostawiłbym jako źródło.
Poprawnie działających plików WOFF2 nie wymieniałbym tylko dla wyższego procentu w tabeli. Czasem więcej daje ograniczenie nieużywanych odmian, zmiana sposobu ładowania albo zajęcie się innym zasobem, a obrazy, JavaScript i odpowiedź serwera opisuję w siedmiu sposobach na przyspieszenie strony.
Po wdrożeniu WOFF2 sprawdź w DevTools, czy przeglądarka pobiera właściwy plik, a moduł Performance w CometWeb Insight pomoże ocenić wydajność całej strony po tej zmianie. Załóż darmowe konto w Insight, wpisz adres strony i wybierz zakres skanu.
Najczęstsze pytania
Czy WOFF2 jest lepszy od TTF na stronie internetowej?
Do wysyłania fontu przeglądarkom WOFF2 jest lepszy, bo pakuje te same dane w mniejszy plik i obsługuje go każda popularna przeglądarka. TTF zostaje pełnoprawnym plikiem źródłowym, więc zachowaj oryginał i serwuj sprawdzony plik WOFF2.
Czy WOFF2 pogarsza wygląd liter?
WOFF2 zachowuje kształty liter, a w moim teście ta sama czcionka w obu formatach dała identyczne piksele. Wygląd może zmienić dopiero podzbiór znaków albo usunięcie hintingu, które niektóre konwertery robią przy okazji.
Czy muszę wysyłać jednocześnie TTF i WOFF2?
Nowoczesnym przeglądarkom wystarczy WOFF2. WOFF dodaj tylko wtedy, gdy wymaga go któreś ze wspieranych środowisk, i wpisz go po WOFF2 na tej samej liście src.
Czy mogę przekonwertować WOFF na WOFF2?
Tak, sama konwersja WOFF na WOFF2 jest bezstratna. Wyjdź jednak od oryginału, bo konwersja istniejącego podzbioru nie przywróci znaków, które już z niego usunięto.
Czy mniejszy font poprawi Core Web Vitals?
Mniejszy font zmniejsza liczbę pobieranych bajtów, ale o LCP i CLS decyduje też strategia ładowania i metryki fontu zastępczego. Efekt sprawdź na działającej stronie, przed zmianą i po niej.
Czy wystarczy zmienić rozszerzenie pliku z .ttf na .woff2?
Zmiana rozszerzenia nic nie da, bo w środku nadal zostaje nieskompresowany TTF, a plik WOFF2 powstaje dopiero po zakodowaniu fontu konwerterem.
Pełne wyniki pomiaru
Redukcja jest liczona względem oryginału, a ostatnia kolumna pokazuje, o ile WOFF2 był mniejszy od oryginału skompresowanego samym Brotli.
Font | Kontury | Oryginał (B) | WOFF2 (B) | Redukcja | Brotli (B) | WOFF2 vs Brotli |
|---|---|---|---|---|---|---|
Arial Unicode | glyf | 23 278 008 | 11 357 648 | 51,2% | 12 921 359 | +12,1% |
SF Pro (zmienny) | glyf | 8 333 964 | 2 757 524 | 66,9% | 2 780 939 | +0,8% |
Times New Roman | glyf | 824 920 | 361 816 | 56,1% | 403 946 | +10,4% |
Courier New | glyf | 684 624 | 310 384 | 54,7% | 351 676 | +11,7% |
Georgia | glyf | 379 588 | 110 840 | 70,8% | 130 472 | +15,0% |
Verdana | glyf | 186 188 | 78 648 | 57,8% | 90 649 | +13,2% |
Noto Sans Siddham | CFF | 94 408 | 50 092 | 46,9% | 50 562 | +0,9% |
Noto Sans Javanese | CFF | 86 944 | 38 828 | 55,3% | 38 821 | -0,0% |
Noto Sans Canadian Aboriginal | CFF | 41 468 | 23 788 | 42,6% | 23 992 | +0,9% |
Noto Sans Tifinagh | CFF | 24 956 | 13 304 | 46,7% | 13 215 | -0,7% |
Noto Sans Thaana | glyf | 18 792 | 8 200 | 56,4% | 9 088 | +9,8% |
Noto Sans Phoenician | glyf | 6 252 | 3 476 | 44,4% | 3 769 | +7,8% |
Noto Sans Lycian | glyf | 4 556 | 2 200 | 51,7% | 2 560 | +14,1% |
Źródła i dane z testu
- Pakiet badania: metodologia, wersje narzędzi i sumy kontrolne
- Wyniki rozmiarów plików
- Sprawdzenie w przeglądarce
- Skrypt pomiaru
- W3C: WOFF File Format 2.0
- W3C: CSS Fonts Module Level 4, deskryptor src
- MDN: unicode-range, font-display, rel=preload
- Can I use: WOFF 2.0
Pakiet nie zawiera samych fontów, bo to fonty systemowe licencjonowane przez ich dostawców, więc zanim wrzucisz font do sieci, sprawdź, czy masz do tego prawo.