Font Loading Strategy
Kiểm soát cách tải font (ví dụ: font-display: swap) để tránh chặn hiển thị và cải thiện LCP.
Font Loading Strategy là gì?
Font Loading Strategy (chiến lược tải font) là cách trình duyệt xử lý việc tải, hiển thị và thay thế phông chữ tùy chỉnh trên trang web — đặc biệt khi dùng @font-face. Mục tiêu chính là đảm bảo nội dung văn bản hiện ra nhanh nhất có thể, không bị chặn bởi việc chờ font tải xong, từ đó cải thiện trải nghiệm người dùng và các chỉ số hiệu năng như Largest Contentful Paint (LCP).
Chiến lược này được kiểm soát chủ yếu qua thuộc tính font-display trong CSS, với các giá trị như auto, block, swap, fallback, và optional. Mỗi giá trị quy định thời gian chờ hiển thị văn bản và hành vi thay thế font sau khi tải xong.
Tại sao quan trọng trong SEO?
Google xếp hạng trang web dựa một phần vào trải nghiệm người dùng trên thiết bị di động và tốc độ tải. Trong Core Web Vitals, LCP (thời điểm phần tử lớn nhất trong khung nhìn được hiển thị đầy đủ) là chỉ số bắt buộc. Nếu font chưa tải xong mà trình duyệt chặn hiển thị văn bản (ví dụ với font-display: block và thời gian chờ dài), LCP sẽ bị chậm — làm giảm điểm hiệu năng và ảnh hưởng gián tiếp đến thứ hạng.
Ngoài ra, việc chặn hiển thị văn bản (FOIT – Flash of Invisible Text) gây khó chịu cho người dùng: họ thấy màn hình trắng hoặc khoảng trống thay vì nội dung. Điều này làm tăng tỷ lệ thoát và giảm thời gian ở lại trang — hai tín hiệu gián tiếp Google dùng để đánh giá chất lượng trang.
Cách hoạt động
Khi trình duyệt gặp quy tắc @font-face, nó bắt đầu tải font theo chiến lược được khai báo. Quá trình gồm ba giai đoạn:
- Giai đoạn chặn (Block period): Trình duyệt không hiển thị văn bản bằng font đó, dùng font dự phòng tạm thời nếu có — nhưng giữ vị trí trống nếu không cấu hình đúng.
- Giai đoạn hoán đổi (Swap period): Sau khi hết thời gian chặn, trình duyệt hiển thị văn bản bằng font dự phòng, rồi thay thế bằng font gốc ngay khi tải xong.
- Giai đoạn kết thúc: Font gốc được áp dụng hoàn toàn. Nếu font không tải được, trình duyệt giữ nguyên font dự phòng.
Hành vi cụ thể phụ thuộc vào giá trị font-display và thời gian tải thực tế của font — không phải do lập trình viên đặt cứng.
Hướng dẫn thực hiện
Dưới đây là các bước triển khai an toàn và hiệu quả:
- Ưu tiên font hệ thống trước: Dùng danh sách font dự phòng hợp lý trong
font-family, ví dụ:font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; - Áp dụng
font-display: swapcho mọi font tùy chỉnh — trừ trường hợp đặc biệt (xem bảng bên dưới). Đây là giá trị được khuyến nghị mạnh mẽ bởi Google và các chuyên gia hiệu năng. - Tối ưu kích thước font: Dùng định dạng
WOFF2(nén tốt nhất), loại bỏ glyph không cần thiết (subsetting), và chỉ tải font cho ngôn ngữ đang dùng. - Preload font quan trọng: Với font dùng ngay ở phần đầu trang (ví dụ tiêu đề LCP), thêm thẻ
<link rel="preload">trong<head>:
<link rel="preload" href="/fonts/inter-bold.woff2" as="font" type="font/woff2" crossorigin>
- Tránh @import trong CSS: Dùng
<link rel="stylesheet">thay vì@importtrong file CSS — vì@importgây tải tuần tự, làm chậm font.
Lỗi thường gặp
- Dùng
font-display: blockcho font hiển thị chính: Gây FOIT kéo dài, làm chậm LCP rõ rệt. → Khắc phục: Chuyển sangswaphoặcfallback. - Không khai báo
crossoriginkhi preload font: Trình duyệt bỏ qua preload nếu font nằm trên CDN khác miền. → Khắc phục: Luôn thêmcrossoriginvào thẻ<link rel="preload">. - Tải quá nhiều biến thể font (Bold, Italic, ExtraBold...): Làm tăng số yêu cầu và tổng kích thước tải. → Khắc phục: Chỉ tải biến thể thực sự cần; dùng
font-weightvàfont-stylephù hợp trong CSS để khớp với file đã tải. - Bỏ qua font dự phòng trong
font-family: Khi font gốc thất bại, trình duyệt có thể hiển thị font không mong muốn hoặc gây nhảy layout. → Khắc phục: Luôn khai báo ít nhất 2–3 font dự phòng phù hợp về kiểu dáng và tỷ lệ.
Ví dụ thực tế
Một trang tin tức sử dụng font 'Noto Serif' cho tiêu đề bài viết — phần tử LCP thường là ảnh kèm tiêu đề. Trước khi tối ưu:
@font-face {
font-family: 'Noto Serif';
src: url('/fonts/noto-serif.woff2') format('woff2');
font-weight: 700;
}
Sau khi áp dụng chiến lược tốt:
<link rel="preload" href="/fonts/noto-serif-bold.woff2" as="font" type="font/woff2" crossorigin>
@font-face {
font-family: 'Noto Serif';
src: url('/fonts/noto-serif-bold.woff2') format('woff2');
font-weight: 700;
font-display: swap;
font-style: normal;
}
h1 {
font-family: 'Noto Serif', Georgia, 'Times New Roman', serif;
}
Kết quả đo bằng Lighthouse: LCP cải thiện từ 3.8s → 1.9s trên mạng 3G mô phỏng; không còn hiện tượng trắng màn hình khi tải.
Câu hỏi thường gặp
font-display: swap có gây nhảy layout (layout shift) không?
Có thể xảy ra nếu font gốc và font dự phòng có chiều cao dòng (line-height), khoảng cách ký tự (letter-spacing) hoặc chiều rộng khác biệt rõ rệt. Để giảm thiểu: dùng size-adjust, ascent-override, descent-override (hỗ trợ từ Chrome 106+), hoặc chọn font dự phòng có thông số tương đồng.
Có nên dùng font-display: optional không?
optional cho phép trình duyệt bỏ qua tải font nếu thấy không cần thiết (ví dụ: mạng chậm, thiết bị cũ). Tuy nhiên, hành vi này không đảm bảo — và có thể khiến font không bao giờ xuất hiện. Chỉ dùng khi font mang tính trang trí thuần túy, không ảnh hưởng đến nội dung chính. Với font hiển thị văn bản, swap an toàn và kiểm soát hơn.
Font loading strategy ảnh hưởng đến SEO trực tiếp hay gián tiếp?
Ảnh hưởng gián tiếp: Google không phạt trang vì dùng font-display: block, nhưng nếu điều đó kéo theo LCP > 2.5s và CLS cao, trang sẽ bị đánh giá thấp trong Core Web Vitals — một nhóm tín hiệu xếp hạng xác định. Vì vậy, tối ưu font là phần thiết yếu của On-Page SEO hiện đại.
| Giá trị font-display | Thời gian chặn (ms) | Hành vi khi font chưa tải xong | Phù hợp với |
|---|---|---|---|
auto |
Tùy trình duyệt (thường ~100ms) | FOIT ngắn, sau đó swap | Không khuyến nghị — thiếu kiểm soát |
block |
~3000ms (Chrome) | FOIT kéo dài — văn bản ẩn | Logo, biểu tượng — không dùng cho nội dung |
swap |
0ms | Hiển thị ngay bằng font dự phòng | Khuyến nghị hàng đầu cho font nội dung |
fallback |
~100ms | FOIT rất ngắn, sau đó swap — nếu font tải chậm quá, giữ font dự phòng | Trang yêu cầu cân bằng giữa hiển thị nhanh và độ chính xác font |
optional |
0ms | Không hiển thị font gốc nếu trình duyệt quyết định không tải | Font trang trí, không ảnh hưởng nội dung |