Font memuat

Bagaimana web font memuat memengaruhi Core Web Vitals like CLS dan LCP, font-display strategies, preloading fonts, dan reducing layout shift dari font swaps.

Pertama kali diterbitkan: 2 Jul 2026 · Terakhir diperbarui: 8 Agu 2026 · Advanced
Bahasa

Custom web fonts adalah external files itu memiliki untuk download sebelum text dapat render di them, so browser perlu sebuah plan untuk apa untuk tampilkan di meantime. itu plan — set mainly oleh CSS font-display property — moves dua Core Web Vitals: LCP (ketika sebuah render-blocking font delays Anda largest text) dan CLS (ketika swapping fallback untuk web font shifts layout). dua default behaviors, FOIT dan FOUT, setiap memiliki sebuah failure mode. reliable memperbaiki: preload critical fonts, gunakan font-display: opsional atau tukar dengan sengaja, match Anda fallback font's metrics, atau skip custom fonts entirely. ini adalah tidak sebuah direct peringkat factor — ini feeds CLS/LCP, yang adalah pengalaman halaman sinyal.

TL;DR — Custom web fonts adalah render-affecting external resources. mereka hit LCP ketika sebuah render-blocking font delays Anda largest text element, dan CLS ketika fallback-untuk-web-font tukar reflows layout. dua default behaviors — FOIT (invisible until dimuat) dan FOUT (fallback lalu tukar) — setiap fail differently. font-display adalah utama lever (swap jaminan FOUT; optional memberikan sebuah ~100ms window dan lalu commits, killing kemudian tukar). Preloading memperbaiki late font penemuan; preload + font-display: optional adalah combo Google’s own engineering singled out untuk eliminating layout jank. tetapi passing Lighthouse font-display periksa tidak perbaiki CLS — itu perlu sebuah metrically-cocok fallback (atau size-adjust/ascent-override overrides). None dari ini adalah sebuah direct peringkat factor; ini feeds CLS/LCP, yang adalah pengalaman halaman sinyal.

Evidence for this claim The CSS Font Loading API exposes font loading state and control to documents. Scope: Current official or standards documentation. Confidence: high · Verified: MDN: CSS Font Loading API Evidence for this claim font-display controls how a font face is displayed while it downloads and when fallback is used. Scope: Current official or standards documentation. Confidence: high · Verified: MDN: font-display

Mengapa fonts adalah sebuah special case

sebagian besar performa masalah adalah tentang bytes — sebuah image adalah too big, sebuah script blocks main utas. Fonts adalah worse daripada itu di satu spesifik cara: mereka’re sebuah external resource dan mereka perubahan metrics dari Anda text. So sebuah font dapat hurt Anda dua berbeda cara di setelah. ini dapat delay ketika text paints (sebuah LCP masalah), dan ini dapat perubahan size dan shape dari itu text setelah ini adalah sudah pada screen (sebuah CLS masalah).

dua default browser behaviors adalah worth naming karena seluruh topic hangs off them:

  • FOIT (Flash dari Invisible Text): text di custom font adalah dirender invisible until font memuat atau sebuah timeout adalah hit — secara historis up untuk sebuah ~3-kedua block di sebagian besar browser.
  • FOUT (Flash dari Unstyled Text): fallback font menampilkan immediately, lalu mendapatkan ditukar untuk web font setelah ini memuat.

FOIT feels “cleaner” (terjemahan) “cleaner” (Tidak jump) tetapi risks sebuah rendering delay. FOUT feels lebih cepat (text now) tetapi risks sebuah layout shift pada tukar. Neither adalah secara otomatis safe — itu’s core idea untuk hold onto.

ini juga helps untuk terpisah pipeline ke distinct stages, karena success di satu stage tidak jaminan success di berikutnya. sebuah @font-face aturan hanya declares sebuah face — browser fetches sebenarnya font file hanya setelah matching styled text pada halaman memerlukan ini (declaration dan matching adalah terpisah langkah dari fetch). itu fetch adalah subject untuk CORS jika font adalah disajikan cross-origin, so sebuah stylesheet itu memuat cleanly tidak jaminan font respons itself carries right cross-origin permission — sebuah missing header di sana fails silently sebagai sebuah font itu tidak pernah renders. dan sebuah successful fetch masih tidak jaminan sebuah stable-looking halaman: cold-cache, warm-cache, dan sudah-cached font status dapat produce berbeda penemuan dan tukar timing, so testing satu repeat pemuatan halaman di DevTools tidak tell Anda apa sebuah pertama-time pengunjung sebenarnya sees.

Bagaimana fonts memengaruhi LCP

jika largest terlihat element pada Anda halaman adalah text — sebuah big headline, sebuah hero paragraf — lalu font itu text menggunakan dapat become bagian dari Anda LCP path. Per web.dev’s LCP guidance, LCP resource dari sebuah halaman, jika ini memiliki satu, akan menjadi either sebuah image atau sebuah web font. sebuah render-blocking font itu leaves itu text invisible (FOIT) pushes Anda LCP out until font arrives.

perbaiki di sini adalah straightforward dan muncul straight dari Google. pada web.dev’s mengoptimalkan Largest Contentful Paint guide:

“If you set a font-display value of anything other than auto or block, then text will always be visible during load, and LCP won’t be blocked on an additional network request.” (terjemahan) “Jika Anda menetapkan nilai font-display selain auto atau block, teks akan tetap terlihat selama pemuatan, dan LCP tidak akan terhalang oleh permintaan jaringan tambahan.”web.dev

dengan kata lain: swap, fallback, atau optional semua pertahankan text terlihat selama muat, so Anda LCP tidak hostage untuk font permintaan.

Bagaimana fonts memengaruhi CLS

CLS muncul dari tukar. Anda fallback font dan Anda web font hampir tidak pernah memiliki identical character widths dan line heights, so ketika browser replaces satu dengan lainnya, text reflows — dan semuanya di bawah ini moves. itu’s sebuah layout shift.

counterintuitive bagian, dan hal sebagian besar orang miss: FOIT penyebab CLS too. bahkan invisible text adalah masih laid out menggunakan fallback font’s metrics, so tukar masih moves hal. dari web.dev’s mengoptimalkan Cumulative Layout Shift guide:

“Keduanya approaches dapat penyebab layout shifts. Even jika itu text adalah invisible, ini masih laid out menggunakan itu fallback font, so ketika itu web font loads, itu text block dan itu sekitarnya konten shift” (terjemahan) “Keduanya approaches dapat penyebab layout shifts. bahkan jika text adalah invisible, ini adalah masih laid out menggunakan fallback font, so ketika web font memuat, text block dan sekitarnya konten shift”web.dev

yang sama halaman frames dua behaviors plainly:

“Itu fallback font adalah ditukar dengan itu web font, incurring a Flash dari Unstyled Text (FOUT). ‘Invisible’ text adalah displayed menggunakan itu fallback font until a web font adalah tersedia dan itu text adalah membuat visible (FOIT—flash dari invisible text).” (terjemahan) “ fallback font adalah ditukar dengan web font, incurring sebuah Flash dari Unstyled Text (FOUT). ‘Invisible’ text adalah displayed menggunakan fallback font until sebuah web font adalah tersedia dan text adalah dibuat terlihat (FOIT—flash dari invisible text).”web.dev

I’ve mengatakan yang sama hal di plainer istilah di my Ahrefs tulis-up pada Cumulative Layout Shift: ketika sebuah font memuat atau perubahan, Anda end up dengan sebuah noticeable shift — sebuah FOIT atau sebuah FOUT. ini adalah satu dari paling umum dunia nyata CLS penyebab, right alongside images tanpa dimensions dan konten injected setelah muat.

font-display property

font-display adalah sebuah @font-face descriptor itu controls dua windows: block period (bagaimana panjang browser hides text menunggu untuk font) dan tukar period (bagaimana panjang, setelah block period, ini akan masih tukar di web font setelah ini arrives). Per web.dev’s Best Practices untuk Fonts:

nilaiBlock periodTukar period
autobrowser-dependentbrowser-dependent
block2–3 secondsInfinite
swap0msInfinite
fallback100ms3 seconds
optional100msNone

MDN’s font-display reference, yang Google’s own docs tautan untuk sebagai spec sumber, mendeskripsikan them tersely: swap memberikan sebuah extremely kecil block period dan sebuah infinite tukar period; optional memberikan sebuah extremely kecil block period dan Tidak tukar period. itu “Tidak tukar period” (terjemahan) “Tidak tukar period” adalah seluruh poin dari optional — setelah block period window closes, whatever font adalah di gunakan tetap, so ada Tidak kemudian tukar untuk shift layout.

Satu caution pada angka di itu table: CSS specification itself hanya defines block/tukar period categories — pendek, extremely kecil, infinite, none — dan leaves tepat duration untuk browser. millisecond/kedua figures di atas adalah web.dev’s terdokumentasi Chromium perilaku, tidak sebuah cross-browser jaminan. Treat them sebagai illustrative alih-alih sebuah spec promise, dan periksa saat ini angka untuk whichever browser/versi Anda’re sebenarnya testing terhadap.

Yang nilai untuk yang konten? web.dev’s own advice adalah itu ini dapat menjadi mixed: gunakan swap untuk branding dan lainnya visually distinctive elements (di mana seeing brand font penting dan sebuah brief shift adalah acceptable), dan optional untuk body text (di mana CLS-sensitivity wins dan Anda’d rather tidak shift). itu’s sebuah genuinely berguna aturan dari thumb — jangan apply satu nilai situs-wide oleh reflex.

Preloading fonts

Font permintaan adalah ditemukan late. browser tidak know ini perlu sebuah font until ini memiliki parsed Anda CSS, cocok sebuah @font-face aturan untuk sebuah element pada halaman, dan decided itu element adalah terlihat. hanya lalu melakukan ini mulai download. sebuah <link rel="preload"> pendek-circuits itu:

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

itu tells browser untuk mulai fetching font immediately, di parallel dengan semuanya else, alih-alih menunggu untuk menemukan ini. Bing’s engineering team mendeskripsikan persis ini mechanism pada mereka own penelusuran halaman (lebih di Quotes tab): preload tags di <head> kick off font downloads right away, whereas tanpa them browser tidak akan fetch fonts until ini memiliki parsed CSS dan ditemukan matching elements.

** strongest combination** per Google’s own writeup adalah preload + font-display: optional. web.dev’s mencegah layout shifting dan FOIT oleh preloading opsional fonts panggilan combining <link rel="preload"> dengan font-display: optional paling effective cara untuk jaminan Tidak layout jank ketika rendering custom fonts, dan notes itu Chrome (dari versi 83) eliminated layout shifting itu digunakan untuk happen ketika preloading opsional fonts. preload memberikan font -nya best shot di arriving di dalam ~100ms window; optional jaminan itu jika ini tidak, Anda tidak pay untuk ini dengan sebuah shift.

Ketika tidak untuk preload. Preloading tidak free. web.dev warns itu preload adalah highly effective di membuat fonts discoverable early, tetapi ini muncul di cost dari taking browser resources away dari memuat lainnya resources. Preload satu atau dua fonts Anda sebenarnya perlu di atas fold — preloading setiap font weight Anda own dapat starve lebih penting resources dan membuat halaman lebih lambat overall.

pastikan preload sebenarnya mendapatkan reused. sebuah preload hanya helps jika browser dapat match ini untuk nyata font permintaan — href, as="font", type, dan crossorigin mode semua memiliki untuk line up dengan apa CSS @font-face aturan ends up requesting, atau Anda’ll mendapatkan sebuah “unused preload” (terjemahan) “unused preload” warning dan sebuah wasted kedua download alih-alih sebuah lebih cepat satu. Preloading dapat juga bypass unicode-range selection, pulling down sebuah subset Anda tidak sebenarnya perlu untuk itu halaman. Konfirmasi match di DevTools’ Network panel: Anda ingin see satu permintaan untuk itu font, kicked off oleh preload, tidak dua.

Memperbaiki shift itself: fallback metric matching

Di sini’s trap: passing Lighthouse font-display periksa melakukan tidak perbaiki CLS. Google’s Lighthouse docs adalah jelas itu FOIT dan FOUT memiliki yang sama impact pada CLS setelah custom font replaces temporary sistem font. So swap membuat Anda text terlihat (baik untuk LCP dan untuk “invisible text” (terjemahan) “invisible text” audit) tetapi leaves tukar shift di place.

untuk kill shift ketika sebuah tukar melakukan happen, Anda memiliki untuk membuat fallback font dan web font take up yang sama space. Dua levers:

  1. Pick sebuah metrically-similar sistem fallback di Anda font-family stack, rather daripada sebuah single custom font name dengan tidak ada apa pun sensible behind ini. closer fallback’s character widths dan line height adalah untuk web font, lebih kecil shift.
  2. Override web font’s metrics dengan size-adjust, ascent-override, descent-override, dan line-gap-override pada @font-face aturan, so web font adalah forced untuk match fallback’s box. web.dev lists ini descriptors, dan Smashing Magazine’s deep dive pada CSS font descriptors walks melalui them di detail jika Anda ingin go semua cara.

setiap dari itu four descriptors adjusts sebuah berbeda metric, dan saat ini browser mendukung varies oleh descriptor — periksa compatibility sebelum leaning pada apa pun single satu. Validate terhadap sebenarnya weights, styles, dan scripts Anda ship, too: sebuah perbaiki confirmed pada Anda regular-weight Latin text tidak jaminan bold, italic, atau sebuah non-Latin script behave yang sama cara.

DebugBear’s Memperbaiki Layout Shifts Disebabkan oleh Web Fonts adalah sebuah baik end-untuk-end walkthrough dari ini: mengukur impact, identify masalah font, apply font-display, choose sebuah better fallback, lalu adjust font metrics.

Google Fonts vs. self-hosting

Anda tidak memiliki untuk self-host untuk control font-display. Google Fonts CSS2 API accepts sebuah display kueri parameter — https://fonts.googleapis.com/css2?family=Roboto&display=swap sets font-display secara langsung pada disajikan @font-face aturan. Addy Osmani’s post pada shipping font-display untuk Google Fonts covers perubahan: previously satu-satunya cara untuk specify font-display untuk Google Fonts adalah untuk self-host them, dan ini dihapus itu perlu.

Self-hosting masih wins pada satu hal: ini eliminates extra DNS lookup dan connection untuk fonts.googleapis.com dan fonts.gstatic.com. itu’s sebuah nyata latency cost, dan satu dari alasan sebuah preconnect resource hint untuk itu origins helps jika Anda melakukan gunakan Google Fonts. Weigh connection overhead terhadap convenience — dan jangan assume “it’s from Google, so it’s fine.” (terjemahan) “ini adalah dari Google, so ini adalah fine.” sebuah copy-pasted Google Fonts embed adalah masih sebuah render-blocking stylesheet permintaan plus sebuah font permintaan, dan older embeds dapat tidak carry sebuah display nilai di semua.

ada Tidak universal winner antara dua options — ini muncul down untuk yang scripts dan weights Anda sebenarnya ship, Anda caching setup, dan font’s license istilah. Jalankan perbandingan terhadap Anda own halaman alih-alih menggunakan default untuk whichever satu sebuah tutorial recommended.

Variable fonts

sebuah variable font packs banyak weights dan styles (regular, bold, condensed, italic) ke sebuah single file dengan adjustable axes. itu dapat menjadi sebuah net win — satu permintaan alih-alih dari six — jika Anda sebenarnya gunakan several dari itu variants. tetapi sebuah penuh variable font adalah sebuah bigger single file daripada satu static weight, so jika Anda hanya ever render satu weight, shipping seluruh variable font dapat menjadi lebih lambat, tidak lebih cepat. Subset ini untuk axes dan characters Anda gunakan, sajikan ini sebagai WOFF2 so ini adalah compressed, dan periksa font’s license — tidak setiap foundry permits subsetting atau self-hosting.

Reducing file di pertama place

Semuanya di atas manages ketika font memuat. Anda dapat juga shrink apa memuat. Font subsetting strips out glyphs Anda tidak gunakan (sebuah semua-Latin situs tidak perlu Cyrillic dan CJK ranges), dan WOFF2 adalah well-compressed format untuk sajikan. sebuah lebih kecil font file adalah lebih mungkin untuk arrive di dalam optional’s window dan lebih kecil kemungkinannya untuk block LCP — subsetting dan compression adalah complementary lever untuk font-display dan preload, tidak sebuah alternative untuk them.

ada Tidak single “correct” (terjemahan) “correct” subset atau universal byte-savings percentage di sini, though — ini bergantung pada scripts, characters, dan weights Anda spesifik audience sebenarnya perlu. sebuah angka Anda saw di seseorang else’s case study atau benchmark tidak sebuah promise untuk Anda halaman; mengukur Anda own font permintaan sebelum dan setelah.

adalah ini sebuah peringkat factor?

menjadi precise di sini. Font memuat adalah tidak sebuah direct peringkat factor. Apa ini memengaruhi adalah CLS dan LCP, yang adalah Core Web Vitals dan bagian dari Google’s pengalaman halaman sinyal. dan pengalaman halaman adalah sebuah lightweight, tiebreaker-style sinyal — relevance dan quality dominate; ini helps decide antara jika tidak comparable hasil, tidak antara sebuah great halaman dan sebuah poor satu. So honest framing adalah: perbaiki Anda font memuat karena ini adalah sebuah genuine pengguna-experience masalah itu happens untuk feed dua peringkat inputs — tidak karena sebuah font-display nilai akan move Anda up hasil pada -nya own.

My own take

di seluruh my Ahrefs CLS dan LCP guides I’ve landed pada yang sama priority order, dan ini masih holds. jika Anda dapat gunakan sistem font, melakukan itu — ada tidak ada apa pun untuk muat, so tidak ada delays atau perubahan itu penyebab sebuah shift. jika Anda memiliki untuk gunakan custom font, saat ini best metode untuk minimizing CLS adalah untuk combine <link rel="preload"> (grab font segera setelah mungkin) dengan font-display: opsional (memberikan ini sebuah kecil window untuk muat); jika ini tidak membuat ini di time, halaman hanya menampilkan sebuah default font, dan Anda custom font mendapatkan cached dan menampilkan up pada subsequent memuat. Preload, lalu optional, lalu — best dari semua — hanya jangan gunakan custom font. itu’s seluruh ladder.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.