Hướng dẫn về Font Loading

Cách web font loading ảnh hưởng Core Web Vitals như CLS và LCP, font-display strategies, preloading fonts, và reducing layout shift từ font swaps.

Xuất bản lần đầu: 2 thg 7, 2026 · Cập nhật lần cuối: 8 thg 8, 2026 · Advanced
Ngôn ngữ

Custom web fonts là external files đó có để download trước text có thể render trong them, so đó trình duyệt cần một plan cho điều cần cho thấy trong đó meantime. Đó plan — set mainly by đó CSS font-display property — moves hai Core Web Vitals: LCP (khi một render-blocking font delays của bạn largest text) và CLS (khi swapping đó fallback cho đó web font shifts đó layout). Đó hai default behaviors, FOIT và FOUT, mỗi có một chế độ lỗi. Đó reliable các cách sửa: preload cốt yếu fonts, dùng font-display: tùy chọn hoặc đổi có chủ ý, match của bạn fallback font các chỉ số, hoặc skip custom fonts hoàn toàn. đây là không một trực tiếp xếp hạng factor — điều này feeds CLS/LCP, mà là trang experience các tín hiệu.

Tóm tắt — Custom web fonts là render-affecting external các tài nguyên. họ hit LCP Khi render-blocking font delays của bạn largest text element, và CLS Khi fallback-để-web-font đổi reflows layout. hai default behaviors — FOIT (invisible cho đến khi loaded) và FOUT (fallback sau đó đổi) — mỗi fail differently. font-display là chính lever (swap bảo đảm FOUT; optional cho ~100ms window và sau đó commits, killing sau đó đổi). Preloading các cách sửa muộn font phát hiện; preload + font-display: optional là combo Google own engineering singled out cho eliminating layout jank. nhưng passing Lighthouse font-display kiểm tra không khắc phục CLS — đó cần metrically-khớp fallback (hoặc size-adjust/ascent-override overrides). None của Đây là trực tiếp xếp hạng factor; nó feeds CLS/LCP, mà là trang experience các tín hiệu.

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

Vì sao fonts là special case

phần lớn performance các vấn đề là về bytes — image là cũng big, script chặn main chuỗi trao đổi. Fonts là tệ hơn đó trong một cụ thể way: họ’re external tài nguyên họ thay đổi các chỉ số của bạn text. So font có thể hurt bạn hai khác ways tại sau khi. nó có thể delay Khi text paints ( LCP vấn đề), và nó có thể thay đổi size và shape của đó text sau khi nó đã on screen ( CLS vấn đề).

hai default trình duyệt behaviors là worth naming vì toàn bộ topic hangs off them:

  • FOIT (Flash của Invisible Text): text trong custom font là được kết xuất invisible cho đến khi font loads hoặc timeout là hit — trong lịch sử lên để ~3-thứ hai block trong phần lớn các trình duyệt.
  • FOUT (Flash của Unstyled Text): fallback font hiển thị immediately, sau đó nhận đã đổi cho web font sau khi nó loads.

FOIT feels “cleaner” (không jump) nhưng risks kết xuất delay. FOUT feels nhanh hơn (text hiện tại) nhưng risks layout shift on đổi. Neither là tự động safe — đó cốt lõi ý tưởng để hold onto.

nó cũng helps để tách biệt pipeline vào distinct stages, vì thành công tại một stage không bảo đảm thành công tại tiếp theo. @font-face rule chỉ declares face — trình duyệt fetches thực tế font file chỉ sau khi matching styled text on trang requires nó (declaration và matching là tách biệt steps từ fetch). đó fetch là subject để CORS nếu font là phân phối cross-origin, so stylesheet đó loads cleanly không bảo đảm font phản hồi itself carries right cross-origin permission — bị thiếu header ở đó fails silently as font đó không bao giờ renders. và thành công fetch vẫn không bảo đảm ổn định-looking trang: cold-bộ nhớ đệm, warm-bộ nhớ đệm, và đã-được lưu đệm font trạng thái có thể produce khác phát hiện và đổi timing, so kiểm thử một repeat trang load trong DevTools không tell bạn Điều gì đầu tiên-time khách truy cập thực ra sees.

Cách fonts ảnh hưởng LCP

nếu largest visible element on của bạn trang là text — big headline, hero paragraph — sau đó font đó text dùng có thể become part của bạn LCP path. Theo web.dev LCP hướng dẫn, LCP tài nguyên của trang, nếu nó có một, sẽ là either image hoặc web font. render-blocking font đó leaves đó text invisible (FOIT) pushes của bạn LCP out cho đến khi font arrives.

khắc phục ở đây là straightforward và xuất hiện straight từ Google. On web.dev Optimize Largest Contentful Paint hướng dẫn:

“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.” (bản dịch) «Nếu bạn set một font-display giá trị of bất cứ điều gì other hơn auto hoặc block, thì văn bản sẽ luôn hiển thị trong khi tải, và LCP sẽ không bị chặn bởi một yêu cầu mạng bổ sung.»web.dev

nói cách khác: swap, fallback, hoặc optional all giữ text visible during load, so của bạn LCP không phải hostage để font yêu cầu.

Cách fonts ảnh hưởng CLS

CLS xuất hiện từ đổi. của bạn fallback font và của bạn web font gần như không bao giờ có giống hệt character widths và line heights, so Khi trình duyệt replaces một với khác, text reflows — và mọi thứ dưới nó moves. đó layout shift.

counterintuitive part, và điều phần lớn mọi người miss: FOIT gây ra CLS cũng. Even invisible text là vẫn laid out sử dụng fallback font các chỉ số, so đổi vẫn moves điều. từ web.dev Optimize Cumulative Layout Shift hướng dẫn:

“Both approaches can cause layout shifts. Even if the text is invisible, it’s still laid out using the fallback font, so when the web font loads, the text block and the surrounding content shift” (bản dịch) «Cả hai cách đều có thể gây dịch chuyển bố cục. Ngay cả khi văn bản ẩn, nó vẫn được bố trí bằng phông chữ dự phòng, nên khi phông chữ web tải, khối văn bản và nội dung xung quanh sẽ dịch chuyển»web.dev

giống nhau trang frames hai behaviors plainly:

“The fallback font is swapped with the web font, incurring a Flash of Unstyled Text (FOUT). ‘Invisible’ text is displayed using the fallback font until a web font is available and the text is made visible (FOIT—flash of invisible text).” (bản dịch) «Phông chữ dự phòng được thay bằng phông chữ web, gây ra Flash of Unstyled Text (FOUT) (FOUT). Văn bản «Invisible» được hiển thị bằng phông chữ dự phòng cho đến khi có phông chữ web và văn bản được hiển thị (FOIT — flash of invisible text).»web.dev

I’ve đã nói giống nhau điều trong plainer terms trong my Ahrefs ghi-lên on Cumulative Layout Shift: Khi font loads hoặc thay đổi, bạn end lên với noticeable shift — FOIT hoặc FOUT. nó một của phần lớn phổ biến thực-world CLS gây ra, right alongside images không có dimensions và nội dung injected sau khi load.

font-display property

font-display@font-face descriptor đó controls hai windows: block period (Cách dài trình duyệt hides text đang chờ cho font) và đổi period (Cách dài, sau khi block period, nó sẽ vẫn đổi trong web font sau khi nó arrives). Theo web.dev Thực hành tốt nhất cho Fonts:

Giá trịBlock periodĐổi period
autotrình duyệt-phụ thuộctrình duyệt-phụ thuộc
block2–3 secondsInfinite
swap0msInfinite
fallback100ms3 seconds
optional100msNone

MDN’s font-display reference, mà Google own tài liệu link để as đó spec nguồn, mô tả them tersely: swap cho an extremely nhỏ block period và an infinite đổi period; optional cho an extremely nhỏ block period và không đổi period. Đó “no swap period” (bản dịch) «không đổi period» là đó toàn bộ point of optional — sau đó block period window closes, whatever font là trong dùng vẫn giữ, so có không sau đó đổi để shift đó layout.

Một caution on numbers trong đó bảng: CSS đặc tả itself chỉ defines block/đổi period categories — ngắn, extremely nhỏ, infinite, none — và leaves chính xác duration để trình duyệt. millisecond/thứ hai figures trên là web.dev được ghi lại Chromium behavior, không cross-trình duyệt bảo đảm. Treat them as illustrative thay vì spec promise, và kiểm tra hiện tại numbers cho whichever trình duyệt/version bạn’re thực ra kiểm thử so với.

Mà giá trị cho mà nội dung? web.dev own advice là đó những điều này có thể là mixed: sử dụng swap cho branding và khác visually distinctive elements (nơi seeing brand font matters và brief shift là acceptable), và optional cho thân phản hồi text (nơi CLS-sensitivity wins và bạn’d rather không shift). đó genuinely hữu ích rule của thumb — không apply một giá trị trang web-wide by reflex.

Preloading fonts

Font các yêu cầu là discovered muộn. trình duyệt không know nó cần font cho đến khi nó có parsed của bạn CSS, khớp @font-face rule để element on trang, và decided đó element là visible. chỉ sau đó làm nó bắt đầu download. <link rel="preload"> ngắn-circuits đó:

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

đó tells trình duyệt để bắt đầu fetching font immediately, trong parallel với mọi thứ khác, thay vì đang chờ để discover nó. Bing engineering team mô tả chính xác điều này mechanism on của họ own tìm kiếm các trang (nhiều hơn trong Quotes tab): preload tags trong <head> kick off font downloads right away, whereas không có them trình duyệt sẽ không fetch fonts cho đến khi nó có parsed CSS và tìm thấy matching elements.

** strongest combination** theo Google own writeup là preload + font-display: optional. web.dev Ngăn layout shifting và FOIT by preloading tùy chọn fonts calls combining <link rel="preload"> với font-display: optional phần lớn effective way để bảo đảm không layout jank Khi kết xuất custom fonts, và notes đó Chrome (từ version 83) eliminated layout shifting đó được sử dụng để happen Khi preloading tùy chọn fonts. preload cho font của nó best shot tại arriving bên trong ~100ms window; optional bảo đảm đó nếu nó không, bạn không pay cho nó với shift.

Khi không để preload. Preloading không phải free. web.dev warns đó preload là highly effective tại đang làm fonts discoverable sớm, nhưng nó xuất hiện tại cost của taking trình duyệt các tài nguyên away từ loading khác các tài nguyên. Preload một hoặc hai fonts bạn thực ra cần trên fold — preloading mỗi font weight bạn own có thể starve nhiều hơn quan trọng các tài nguyên và làm trang chậm hơn overall.

Hãy bảo đảm đó preload thực ra nhận reused. MỘT preload chỉ helps nếu đó trình duyệt có thể match điều này để đó real font yêu cầu — đó href, as="font", type, và crossorigin chế độ all có để line lên với điều gì đó CSS @font-face rule ends lên requesting, hoặc bạn’ll nhận an “unused preload” (bản dịch) «unused preload» warning và một wasted second download thay vì một nhanh hơn một. Preloading có thể cũng bypass unicode-range selection, pulling xuống một subset bạn đã không thực ra cần cho đó trang. Xác nhận đó match trong DevTools’ Network panel: bạn muốn để see một yêu cầu cho đó font, kicked off by đó preload, không hai.

Sửa shift itself: fallback chỉ số matching

Ở đây đó trap: passing đó Lighthouse font-display kiểm tra làm không cách sửa CLS. Google Lighthouse tài liệu là rõ ràng đó FOIT và FOUT có đó giống nhau impact on CLS khi đó custom font replaces đó tạm thời hệ thống font. So swap làm của bạn text visible (good cho LCP và cho đó “invisible text” (bản dịch) «invisible text» audit) nhưng leaves đó đổi shift trong place.

để kill shift Khi đổi làm happen, bạn có để làm fallback font và web font take lên giống nhau space. Hai levers:

  1. Pick metrically-similar hệ thống fallback trong của bạn font-family stack, rather hơn single custom font name với không có gì sensible behind nó. closer fallback character widths và line height là để web font, nhỏ hơn shift.
  2. Override web font các chỉ số với size-adjust, ascent-override, descent-override, và line-gap-override on @font-face rule, so web font là forced để match fallback box. web.dev lists những điều này descriptors, và Smashing Magazine deep dive on CSS font descriptors walks qua them trong detail nếu bạn muốn để go all way.

mỗi của những điều đó four descriptors adjusts khác chỉ số, và hiện tại trình duyệt hỗ trợ varies by descriptor — kiểm tra compatibility trước khi leaning on bất kỳ single một. Validate so với thực tế weights, styles, và scripts bạn ship, cũng: khắc phục confirmed on của bạn regular-weight Latin text không bảo đảm bold, italic, hoặc non-Latin script behave giống nhau way.

DebugBear Sửa Layout Shifts Gây ra by Web Fonts là good end-để-end walkthrough của điều này: đo lường impact, identify vấn đề font, apply font-display, chọn tốt hơn fallback, sau đó adjust font các chỉ số.

Google Fonts so với. self-hosting

bạn không có để self-host để control font-display. Google Fonts CSS2 API accepts display query parameter — https://fonts.googleapis.com/css2?family=Roboto&display=swap sets font-display trực tiếp on phân phối @font-face rules. Addy Osmani post on shipping font-display để Google Fonts covers thay đổi: previously chỉ way để specify font-display cho Google Fonts là để self-host them, và điều này đã xóa đó cần.

Self-hosting vẫn wins on một điều: điều này eliminates đó extra DNS lookup và connection để fonts.googleapis.comfonts.gstatic.com. đó là một real latency cost, và một of đó reasons một preconnect tài nguyên hint để những origins helps nếu bạn làm dùng Google Fonts. Weigh đó connection overhead so với đó convenience — và không assume “it’s from Google, so it’s fine.” (bản dịch) «đây là từ Google, so đây là fine.» MỘT copy-pasted Google Fonts embed là vẫn một render-blocking stylesheet yêu cầu plus một font yêu cầu, và older embeds có thể không carry một display giá trị tại all.

có không universal winner giữa hai options — nó xuất hiện xuống để mà scripts và weights bạn thực ra ship, của bạn bộ nhớ đệm setup, và font license terms. Chạy so sánh so với của bạn own các trang thay vì dùng mặc định để whichever một tutorial được khuyến nghị.

Variable fonts

variable font packs nhiều weights và styles (regular, bold, condensed, italic) vào single file với adjustable axes. đó có thể là net win — một yêu cầu thay vì của six — nếu bạn thực ra sử dụng several của những điều đó variants. nhưng đầy đủ variable font là bigger single file hơn một static weight, so nếu bạn chỉ bao giờ render một weight, shipping toàn bộ variable font có thể là chậm hơn, không nhanh hơn. Subset nó để axes và characters bạn sử dụng, phục vụ nó as WOFF2 so nó compressed, và kiểm tra font license — không mỗi foundry permits subsetting hoặc self-hosting.

Reducing file trong đầu tiên place

Mọi thứ trên manages Khi font loads. Bạn có thể cũng shrink Điều gì loads. Font subsetting strips out glyphs bạn không sử dụng ( all-Latin trang web không cần Cyrillic và CJK ranges), và WOFF2 là well-compressed format để phục vụ. nhỏ hơn font file là nhiều hơn có khả năng để arrive bên trong optional’s window và ít hơn có khả năng để block LCP — subsetting và compression là complementary lever để font-display và preload, không alternative để them.

có không single “correct” subset hoặc universal byte-savings percentage ở đây, though — nó phụ thuộc vào scripts, characters, và weights của bạn cụ thể audience thực ra cần. number bạn saw trong ai đó khác case study hoặc benchmark không phải promise cho của bạn các trang; đo lường của bạn own font các yêu cầu trước khi và sau khi.

là điều này xếp hạng factor?

là precise ở đây. Font loading là không trực tiếp xếp hạng factor. Điều gì nó ảnh hưởng là CLS và LCP, mà Core Web Vitals và part của Google trang experience các tín hiệu. và trang experience là lightweight, tiebreaker-style tín hiệu — relevance và quality dominate; nó helps quyết định giữa nếu không comparable kết quả, không giữa great trang và poor một. So honest framing là: khắc phục của bạn font loading vì nó genuine người dùng-experience vấn đề đó happens để feed hai xếp hạng inputs — không vì font-display giá trị sẽ move bạn lên kết quả on của nó own.

My own take

Across my Ahrefs CLSLCP các hướng dẫn I’ve landed on giống nhau priority order, và nó vẫn holds. nếu Bạn có thể sử dụng hệ thống font, làm đó — có không có gì để load, so có không delays hoặc thay đổi đó nguyên nhân shift. nếu bạn để sử dụng custom font, hiện tại best phương thức cho minimizing CLS là để combine <link rel="preload"> (grab font as soon as có thể) với font-display: optional (cho nó nhỏ window để load); nếu nó không làm nó trong time, trang chỉ hiển thị default font, và của bạn custom font nhận được lưu đệm và hiển thị lên on subsequent loads. Preload, sau đó optional, sau đó — best của all — chỉ không sử dụng custom font. đó toàn bộ ladder.

Add an expert note

Pin an expert quote

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