Font Loading Strategies — Performance

Font Loading Strategies Font web yang besar bisa menunda text LCP sampai 1-2 detik. Strategi loading font yang benar menentukan apakah user melihat FOIT (text t

Font Loading Strategies

Font web yang besar bisa menunda text LCP sampai 1-2 detik. Strategi loading font yang benar menentukan apakah user melihat FOIT (text tidak terlihat) atau FOUT (text terlihat dengan font fallback dulu).

FOIT vs FOUT

Property font-display

Property ini mengontrol trade-off antara FOIT dan FOUT di @font-face:

ValueBlock PeriodSwap PeriodKapan pakai
autoBrowser defaultBrowser defaultJangan — tidak predictable
block~3sInfiniteLogo/branding yang wajib persis
swap0sInfiniteDefault terbaik — body text
fallback100ms3sFont yang "nice to have"
optional100ms0sFont opsional, hanya kalau sudah cache
@font-face {
  font-family: "Inter";
  src: url("/fonts/inter.woff2") format("woff2");
  font-display: swap;
  font-weight: 400;
  unicode-range: U+0000-00FF; /* Latin saja */
}

Self-Host vs CDN

Preload Font Kritis

Untuk font yang dipakai di above-the-fold text, preload agar browser mulai download di awal (bukan menunggu CSS di-parse dulu):

<link rel="preload" href="/fonts/inter.woff2"
      as="font" type="font/woff2" crossorigin>

Catatan: crossorigin wajib meski font self-hosted — font dianggap CORS resource. Tanpa crossorigin, browser akan download 2× (sekali preload, sekali untuk dipakai CSS).

Font Subsetting dengan unicode-range

File font mengandung glyph untuk ratusan bahasa. Dengan subsetting, browser hanya download chunk yang dibutuhkan:

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153;
}
@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-cyrillic.woff2") format("woff2");
  unicode-range: U+0400-045F;
}

Halaman Bahasa Indonesia hanya download Latin subset (~20KB), bukan full file (~200KB).

Variable Fonts

Satu file bisa menggantikan seluruh family (Regular, Bold, Italic, Light, dst). Contoh: Inter Variable ~110KB vs 6 static file ~330KB total. Sintaks sama tapi font-weight menerima angka bebas:

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-variable.woff2") format("woff2-variations");
  font-weight: 100 900; /* range, bukan fixed */
  font-display: swap;
}

h1 { font-weight: 750; /* nilai bebas */ }

Yang akan kamu pelajari