Performance / Typography

    Font Optimization w Next.js

    next/font (self-hosting, CLS=0), variable fonts (jeden plik dla wszystkich wag), font-display: optional, FOUT/FOIT i GDPR compliance.

    next/font
    CLS = 0
    Variable fonts
    Jeden plik
    font-display: opt
    No FOUT
    Self-hosted
    GDPR safe

    6 strategii ładowania fontów — porównanie

    next/font, Fontsource, Google CDN, Variable Fonts i System Stack — self-hosting, CLS i zastosowanie.

    Narzędzie Typ Self-host CLS Kiedy
    next/font/google Next.js built-in Tak (auto) 0 (size-adjust) Next.js projekty — domyślny wybór
    next/font/local Next.js built-in Tak (manual) 0 (adjustFontFallback) Custom fonty, licencjonowane
    Fontsource npm packages Tak (npm) Manualne (size-adjust) Non-Next.js, Vite, CRA, Remix
    Google Fonts CDN External CDN Nie Może (bez size-adjust) Prototypy — NIE produkcja (GDPR)
    Variable Fonts Format pliku Tak 0 (jeden plik) Multi-weight — jeden plik zamiast wielu
    System Font Stack CSS Brak (OS) 0 (brak ładowania) Admin UI, utility apps, zero latency

    Często zadawane pytania

    Co to jest next/font i jak eliminuje layout shift przy fontach?

    next/font (Next.js 13+): automatyczne self-hosting fontów. Zero layout shift (CLS = 0). Privacy-first — brak zapytań do Google. Automatyczny font-display: optional. Podejścia: next/font/google — Google Fonts. next/font/local — własne fonty. next/font/google użycie: import {Inter} from 'next/font/google'. const inter = Inter({subsets: ['latin'], display: 'swap', variable: '--font-inter'}). html className={inter.variable}. body className={inter.className}. Jak działa: Next.js pobiera font w build time. Hostuje na własnym serwerze. Brak external request do Google Fonts. CSS variable lub className. Eliminacja FOUT/FOIT: font-display: swap — FOUT (Flash of Unstyled Text). font-display: optional — brak FOUT (preferowane). Przy optional: fallback font używany jeśli główny nie załadował w 100ms. Nie podmienia fallback jeśli załadowany po renderze. Preconnect nie jest potrzebny (self-hosted). Size adjustment: adjustFontFallback: true — automatyczne dostosowanie fallback. fallback: ['Arial', 'sans-serif']. Reduce CLS przy ładowaniu fonta. Subset: subsets: ['latin', 'latin-ext'] — tylko potrzebne znaki. Mniejszy rozmiar fonta. weight: ['400', '700'] — tylko potrzebne grubości. axes dla variable fonts. Wiele fontów: const inter = Inter({variable: '--font-inter'}). const roboto = Roboto({variable: '--font-roboto', weight: ['400', '700']}). html className={inter.variable + ' ' + roboto.variable}. Tailwind: fontFamily: {sans: ['var(--font-inter)'], mono: ['var(--font-roboto-mono)']}.

    Variable Fonts — jeden plik dla wszystkich wag?

    Variable Fonts (CSS Fonts Level 4): jeden plik obsługuje wiele wag i stylów. Osie wariacji: wght (weight) — 100 do 900 ciągłe. wdth (width) — condensed do expanded. ital (italic). slnt (slant). opsz (optical size). GRAD (grade). Custom axes (font-specific). font-variation-settings: font-variation-settings: 'wght' 650. Nie musisz używać font-weight: 650. Lub: font-weight: 650 (jeśli font obsługuje). CSS animation: @keyframes {from {font-variation-settings: 'wght' 100} to {font-variation-settings: 'wght' 900}}. Interaktywne: hover -> zmień wght. Scrollowanie -> animuj wght. Popularne variable fonts: Inter — wght 100-900. Roboto Flex — wght + wdth. Geist (Vercel) — wght 100-900. Fira Code — wght dla kodu. next/font z variable: import {Inter} from 'next/font/google'. Inter({weight: 'variable', subsets: ['latin']}). Lub: Inter — automatycznie variable jeśli dostępny. CSS Variable fonts w Tailwind: font-[wght,400..700,900] nie istnieje. Użyj arbitrary: font-variation-settings. @layer base {html {font-variation-settings: 'wght' var(--font-weight, 400)}}. Rozmiar pliku: Inter Regular woff2: ~45KB. Inter Variable woff2: ~95KB. Ale jeden plik zamiast 9 plików (100-900): 9 * 45KB = 405KB vs 95KB. Oszczędność: 310KB. WOFF2 vs WOFF: WOFF2 — Brotli kompresja. Mniejszy 20-30% niż WOFF. Wsparcie: 97% przeglądarek. Używaj WOFF2 jako primary. WOFF jako fallback tylko dla IE11.

    Google Fonts — dlaczego self-hosting jest lepszy?

    Google Fonts problemy: zewnętrzny HTTP request do Google. Blokowanie renderowania przy złej konfiguracji. Privacy (GDPR) — przekazuje IP usera do Google. Niemcy: Google Fonts bez self-hostingu = RODO naruszenie (wyrok sądu 2022). Czas ładowania: DNS lookup + TCP + TLS + HTTP request. Zwykle 100-300ms dodatkowe opóźnienie. Google Fonts optymalizacja (jeśśli musisz): link rel='preconnect' href='https://fonts.googleapis.com'. link rel='preconnect' href='https://fonts.gstatic.com' crossorigin. display=swap parametr w URL. Ale: brak prywatności, zewnętrzny request. Self-hosting z next/font: zero zewnętrznych requestów. GDPR-compliant. Szybszy (własny CDN/server). Automatyczny w Next.js. Self-hosting bez Next.js: Google Fonts Helper (gwfh.mranftl.com). Wybierz font, pobierz pliki. Lub: fontsource package. npm install @fontsource/inter. import '@fontsource/inter/400.css'. Fontsource: wiele fontów. Tree-shakeable. Każda waga oddzielnie. Variable font support. fonttools: Python library. subset fontów. Usuń niepotrzebne glyphs. pyftsubset. Analiza fontów: wakamaifondue.com — variable font explorer. font-face observer: JS library. FontFaceObserver — sprawdź czy font załadowany. Polyfill dla font events. Kritical CSS inline + font swap: inline critical CSS z @font-face. font-display: swap. Pozostałe CSS async. Eliminuje FOUC (Flash of Unstyled Content).

    FOUT, FOIT i font-display — jak eliminować layout shift?

    FOUT (Flash of Unstyled Text): przeglądarka pokazuje tekst fallback fontem. Po załadowaniu: podmienia na docelowy font. Zmiana rozmiarów tekstu -> CLS (layout shift). FOIT (Flash of Invisible Text): przeglądarka nie pokazuje tekstu do załadowania. Białe tekst (invisible). Potem pojawia się. Złe UX — user nie widzi contentu. font-display wartości: auto — zależy od przeglądarki (zwykle block). block — FOIT (3s niewidoczny, potem swap). swap — FOUT (natychmiast fallback, potem swap). fallback — hybrid (100ms block, 3s swap, potem brak swap). optional — 100ms block, jeśli nie załadowany: nie swap. Rekomendacja 2024: font-display: optional — brak FOUT/FOIT. Jeśli 100ms timeout: fallback font pozostaje. Brak layout shift po renderze. Trade-off: font może nie pojawić się przy bardzo wolnym połączeniu. Ale: szybkie połączenia zawsze dostaną font. size-adjust właściwość (CSS): @font-face {font-family: 'Inter Fallback'; src: local('Arial'); size-adjust: 107%; ascent-override: 90%}. Dopasuj metryki fallback do docelowego fonta. next/font oblicza automatycznie (adjustFontFallback). Eliminuje wizualną zmianę przy swap. Preload: link rel='preload' as='font' href='/fonts/inter.woff2' crossorigin. Załaduj font przed parse HTML. Kombinacja: preload + optional = najlepsza wydajność. CLS monitoring: Web Vitals library. window.addEventListener('CLS', log). Chrome DevTools: Performance -> Layout Shifts. Lighthouse CLS score.

    Systemowe fonty, emoji i icon fonts — co zamiast icon fonts?

    System Font Stack: font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif. Różne na różnych OS: macOS — San Francisco. Windows — Segoe UI. Android — Roboto. Linux — Ubuntu/Cantarell. Zero ładowania. Idealny dla utility/admin UI. Tailwind font-sans: już zawiera system stack. ui-sans-serif — nowoczesny system font bez specyfikowania nazwy. Emoji fonts: Twemoji (Twitter): SVG emoji. Każdy system inaczej renderuje. Jednolite emoji przez Twemoji. twemoji library. Noto Emoji (Google): kompletny zestaw. Noto family — wsparcie dla wszystkich języków. Icon Fonts (złe): Font Awesome, Material Icons jako font. Problemy: font requests. Niewidoczne ikoniki przy font blokadzie. Accessibility issues. Brak tree-shaking. Preferable: SVG icons (Lucide, Heroicons, Phosphor). SVG sprite. React icon components. Lucide React: tree-shakeable SVG icons. TypeScript. 1000+ ikon. Heroicons: Tailwind Labs, 288 ikon. @primer/octicons-react: GitHub. react-icons: zbiorcza biblioteka. fa, md, ai, bi, etc. Duży bundle bez tree-shaking. Używaj z caution. SVG icon system: jeden sprite SVG. use href='#icon-name'. HTTP/2 — mniejszy benefit. Inline icons — tree-shakeable. CSS Blend Modes z fontem: mix-blend-mode. Overlay text na obrazie. clip-path dla text. Variable font + CSS animacja: hover {font-weight: 800} -> CSS transition na variable font. Smooth transition między wagami bez FOUT. Tylko jeśli variable font loaded.

    Czytaj dalej

    Powiązane artykuły

    Kontakt

    Skontaktuj się z nami

    Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.

    Wyślij zapytanie

    Bezpłatna wycena w 24h
    Bez zobowiązań
    Indywidualne podejście
    Ekspresowa realizacja

    Telefon

    +48 790 814 814

    Pon-Pt: 9:00 - 18:00

    Email

    adam@fotz.pl

    Odpowiadamy w ciągu 24h

    Adres

    Plac Wolności 16

    61-739 Poznań

    Godziny pracy

    Pon - Pt9:00 - 18:00
    Sob - NdzZamknięte

    Wolisz porozmawiać?

    Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.

    Zadzwoń teraz