System font adalah font yang sudah terpasang di perangkat pengguna. Custom font (web font) adalah file font yang harus diunduh dulu sebelum dipakai. Bayangin kamu mau menulis papan nama. Spidol di laci bisa langsung dipakai. Spidol khusus yang lebih cantik harus dibeli dulu di toko, dan selama menunggu kamu punya dua pilihan: menulis dulu pakai spidol laci lalu menulis ulang nanti, atau membiarkan papannya kosong sampai spidol baru datang. Dua pilihan itu persis yang dilakukan browser dengan teksmu.
🧪 Tebakan cepat: Halaman pesan Bu Sri memakai Poppins tanpa menulis
font-display. Seorang tamu membukanya di sinyal lemah, dan file font-nya belum selesai diunduh. Teks nama kamar dan totalnya tampil pakai font sistem dulu, atau gak tampil sama sekali? Jawabannya ada di bagian "font-display: apa yang tampil sambil menunggu".
System font: 0 byte
body { font-family: system-ui, sans-serif; }
system-ui adalah nilai font-family di CSS modern yang berarti "font antarmuka perangkat ini": San Francisco di iPhone dan Mac, Segoe UI di Windows, biasanya Roboto di Android. sans-serif di belakangnya adalah cadangan kalau browser gak mengenal system-ui. Sebelum system-ui ada, orang menulis daftar panjang: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif.
Biayanya: 0 byte, 0 request. Teks langsung tampil, dan pengguna sudah terbiasa dengan bentuk hurufnya. Kekurangannya, halamanmu terlihat sedikit beda di tiap perangkat, dan gak punya ciri khas.
Custom font: berapa byte yang dibayar tamu
Misalkan Bu Sri ingin halamannya pakai Poppins, font gratis dari Google Fonts. Ini ukuran file Poppins Regular (400) yang diukur dari Google Fonts (versi v24):
| Versi file | Byte | Dibanding baris di atasnya |
|---|---|---|
| TTF utuh, format lama | 154.628 | |
| WOFF2 utuh, file yang sama dikemas ulang | 49.716 | 68% lebih kecil |
| WOFF2, cuma huruf Latin (subset) | 7.900 | 84% lebih kecil lagi |
- WOFF2 adalah format font web yang paling kecil: isinya dikompres dengan Brotli, dan didukung semua browser modern.
- Subset artinya file cuma berisi karakter yang dibutuhkan. Poppins utuh juga punya huruf Devanagari untuk bahasa Hindi; halaman berbahasa Indonesia cuma butuh huruf Latin. Google Fonts sudah memecah font-nya per subset, dan browser cuma mengunduh subset yang hurufnya ada di halaman.
Bold (700) adalah file terpisah: TTF 150.292 byte, WOFF2 Latin 7.848 byte. Jadi dua weight: 304.920 byte sebagai TTF, atau 15.748 byte sebagai WOFF2 Latin, 19 kali lebih kecil.
Berapa lama tamu menunggu? Model sederhananya: waktu ≈ satu RTT (waktu bolak-balik ke server) + byte ÷ kecepatan. Dengan setelan "Slow 4G" Lighthouse, 1,6 Mbps (204.800 byte per detik) dan RTT 150 ms:
- WOFF2 Latin: 150 + 15.748 ÷ 204,8 = 150 + 77 = 227 ms.
- TTF: 150 + 304.920 ÷ 204,8 = 150 + 1.489 = 1.639 ms.
Di sinyal lemah, 400 kbps (50.000 byte per detik) dengan RTT 400 ms, TTF-nya butuh 400 + 6.098 = 6.498 ms, dan WOFF2 Latin 400 + 315 = 715 ms. Koneksi baru ke server font menambah waktu lagi, jadi angka ini batas bawah.
font-display: apa yang tampil sambil menunggu
Selama font belum tiba, browser memilih salah satu dari dua:
- FOIT (Flash of Invisible Text): teksnya disembunyikan. Halamannya ada, tapi nama kamar dan total kosong.
- FOUT (Flash of Unstyled Text): teksnya tampil pakai font cadangan dulu, lalu berganti ke Poppins waktu file-nya tiba.
font-display di @font-face yang menentukan:
| Nilai | Teks disembunyikan | Ganti ke font custom |
|---|---|---|
block |
sampai 3 detik | kapan pun font-nya tiba |
swap |
sampai 100 ms, lalu font cadangan | kapan pun font-nya tiba |
fallback |
sampai 100 ms | cuma kalau tiba dalam sekitar 3 detik |
optional |
sampai 100 ms | cuma kalau tiba dalam 100 ms itu, kalau gak ya kunjungan berikutnya |
auto |
ditentukan browser | biasanya sama dengan block |
Jadi jawaban tebakannya: gak tampil sama sekali, sampai 3 detik. Tanpa font-display, nilainya auto, dan kebanyakan browser memperlakukannya seperti block. Dengan TTF di sinyal lemah, tamu menatap halaman tanpa nama kamar dan tanpa total selama 3 detik, lalu teks muncul pakai font cadangan, lalu berganti lagi di detik ke-6,5. Dengan font-display: swap, teks tampil pakai font sistem dalam 100 ms, lalu berganti ke Poppins waktu file-nya tiba.
Kode: memuat Poppins dengan benar
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap">
<style>
.kabut { font-family: "Poppins", system-ui, sans-serif; }
</style>
wght@400;700memuat dua weight saja. Di Poppins tiap weight adalah file sendiri: memuat kesembilan weight-nya berarti 9 file.display=swapmembuat Google menulisfont-display: swapdi tiap@font-face.preconnectmembuka koneksi ke server file font lebih awal, karena CSS-nya datang darifonts.googleapis.comtapi file font-nya darifonts.gstatic.com.system-ui, sans-serifdi belakang Poppins adalah font cadangan yang tampil selama menunggu.
File CSS dari Google itu isinya @font-face seperti ini, satu per weight per subset:
@font-face {
font-family: 'Poppins';
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/poppins/v24/pxiEyp8kv8JHgFVrJJfecnFHGPc.woff2) format('woff2');
unicode-range: U+0000-00FF; /* dipersingkat: huruf Latin */
}
Kalau kamu menyimpan font-nya sendiri (self-host), tulis @font-face yang sama dengan src ke file WOFF2 di server-mu.
⚠️ Jebakan yang sering ketemu
- Lupa
font-display. Nilaiautobiasanya berarti teks gak kelihatan sampai 3 detik di koneksi lambat. - Memuat semua weight. Di font seperti Poppins, tiap weight satu file. Muat cuma yang kamu tulis di CSS.
- Pakai TTF atau OTF di web. File yang sama sebagai WOFF2 68% lebih kecil.
- Gak ada font cadangan. Tulis selalu
system-ui, sans-serifdi belakang nama font custom.
TL;DR: System font (font-family: system-ui, sans-serif) sudah ada di perangkat: 0 byte, langsung tampil. Custom font harus diunduh: Poppins 400 dan 700 sebagai TTF 304.920 byte, sebagai WOFF2 Latin cuma 15.748 byte, jadi pakai WOFF2, subset Latin, dan cuma weight yang dipakai. Selama menunggu, FOIT menyembunyikan teks dan FOUT menampilkan font cadangan dulu. font-display yang mengatur: block sembunyi sampai 3 detik, swap tampilkan font sistem dulu lalu tukar saat font custom tiba, optional cuma tukar kalau tiba dalam 100 ms. Tanpa font-display, kebanyakan browser bersikap seperti block, jadi tulis font-display: swap (atau display=swap di URL Google Fonts).