Font Display Swapping
Thuộc tính CSS (font-display) kiểm soát hành vi hiển thị phông chữ khi đang tải, ảnh hưởng đến CLS và UX.
Font Display Swapping là gì?
Font Display Swapping là cách trình duyệt xử lý việc hiển thị phông chữ tùy chỉnh (custom font) khi chúng chưa tải xong. Đây không phải một tính năng riêng lẻ, mà là kết quả của thuộc tính CSS font-display — cho phép kiểm soát hành vi hiển thị phông: dùng phông dự phòng ngay lập tức, chờ tải xong rồi mới hiện, hay hoán đổi (swap) sau khi tải thành công.
Giá trị phổ biến nhất ảnh hưởng đến swapping là font-display: swap. Khi bật, trình duyệt sẽ:
- Hiển thị nội dung ngay bằng phông dự phòng (fallback font) trong thời gian chờ tải phông gốc;
- Sau khi phông gốc tải xong, tự động thay thế (swap) phông dự phòng bằng phông gốc — mà không làm gián đoạn nội dung;
- Không chặn hiển thị văn bản (no FOIT — Flash of Invisible Text); tránh FOUC nặng nếu dùng
block.
Tại sao quan trọng trong SEO?
Font Display Swapping tác động trực tiếp đến hai chỉ số Core Web Vitals quan trọng: Cumulative Layout Shift (CLS) và First Contentful Paint (FCP), từ đó ảnh hưởng đến thứ hạng tìm kiếm.
Khi phông chưa tải xong mà trình duyệt giữ nguyên vị trí trống (FOIT), người dùng thấy màn hình trắng hoặc nội dung bị che khuất — làm tăng thời gian FCP và gây trải nghiệm tiêu cực. Ngược lại, nếu dùng swap không đúng cách, phông gốc có thể được áp dụng muộn, khiến dòng chữ giãn ra, co lại hoặc đổi kích thước — gây layout shift, làm CLS tăng cao.
Google xác nhận rằng CLS > 0.1 được coi là kém; và font swapping không kiểm soát là một trong những nguyên nhân hàng đầu gây layout shift trên web Việt Nam. Ngoài ra, trải nghiệm người dùng tốt hơn còn giúp giảm tỷ lệ thoát và tăng thời gian ở lại — tín hiệu gián tiếp hỗ trợ SEO.
Cách hoạt động
Thuộc tính font-display có 5 giá trị chính (theo MDN Web Docs):
| Giá trị | Hành vi | Thời gian chặn hiển thị (block period) | Ảnh hưởng đến CLS |
|---|---|---|---|
auto |
Hành vi mặc định của trình duyệt (thường giống block) |
Tùy trình duyệt (thường ~3s) | Cao nếu phông chậm tải |
block |
Chặn hiển thị văn bản cho đến khi phông tải xong hoặc hết thời gian chờ | ~3 giây (Chrome), sau đó dùng fallback | Thấp (không swap), nhưng FCP xấu |
swap |
Dùng fallback ngay → swap sang phông gốc khi tải xong | 0ms | Cao nếu không tối ưu kích thước line-height / font-size |
fallback |
Chờ ngắn (~100ms), sau đó dùng fallback — không swap sau này | ~100ms | Thấp (không swap) |
optional |
Chỉ dùng phông gốc nếu đã có trong bộ nhớ cache; không yêu cầu tải mạng | 0ms | Thấp nhất |
Hướng dẫn thực hiện
- Xác định phông cần tối ưu: Chỉ áp dụng
font-display: swapcho phông thân thiện với web (WOFF2), có kích thước nhỏ (< 100 KB), và dùng cho tiêu đề/đoạn văn chính — không áp cho icon font hoặc phông hiếm. - Thêm
font-displayvào khai báo@font-face:@font-face { font-family: 'Inter'; src: url('inter.woff2') format('woff2'); font-display: swap; }
- Đảm bảo fallback font tương thích: Chọn phông dự phòng cùng họ (serif/sans-serif), gần giống chiều cao dòng (
line-height), kích thước chữ và khoảng cách chữ (letter-spacing). Ví dụ:font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; - Test layout stability: Dùng Chrome DevTools → Tab Rendering → bật Layout Shift Regions; hoặc chạy Lighthouse với kiểm tra CLS. Nếu thấy vùng highlight nhảy sau khi swap, điều chỉnh
font-size,line-heighthoặc dùngsize-adjust(tùy trình duyệt hỗ trợ). - Ưu tiên tải sớm với
preconnectvàpreload:<link rel="preconnect" href="https://fonts.example.com"> <link rel="preload" as="font" href="inter.woff2" type="font/woff2" crossorigin>
Lỗi thường gặp
- Lỗi 1: Swap gây layout shift mạnh
Nguyên nhân: Phông gốc và fallback khác biệt về chiều cao dòng hoặc độ rộng ký tự.
Cách khắc phục: Dùngline-heighttuyệt đối (vd:1.4thay vìnormal); kiểm trafont-sizevàletter-spacingở cả hai phông; thử thêmfont-size-adjust: 0.5;(tùy trình duyệt hỗ trợ). - Lỗi 2: Không thấy hiệu ứng swap dù đã khai báo
Nguyên nhân: Trình duyệt cache phông, hoặc khai báo@font-facebị đè bởi CSS khác, hoặc dùngfont-displaytrong file CSS ngoài mà không hỗ trợ (IE, Safari cũ).
Cách khắc phục: Kiểm tra tab Network trong DevTools để xác nhận phông được tải; dùng Disable cache khi test; kiểm tra tương thích tại caniuse.com/font-display. - Lỗi 3: Dùng
swapcho phông nặng (>150 KB)
Nguyên nhân: Thời gian tải lâu khiến fallback hiển thị quá lâu → người dùng đọc xong phần đầu rồi mới thấy thay đổi → gây khó chịu.
Cách khắc phục: Nén phông (dùng WOFF2 + subsetting); loại bỏ glyph không dùng (ví dụ: chỉ giữ tiếng Việt, không giữ tiếng Nhật/Ả Rập); cân nhắcfont-display: fallbackcho phông phụ.
Ví dụ thực tế
Một trang tin tức tiếng Việt sử dụng phông Roboto cho tiêu đề và Merriweather cho bài viết. Trước tối ưu:
– CLS trung bình: 0.28
– 42% lượt truy cập gặp FOIT kéo dài >1.2s.
Sau khi áp dụng:
– Thay @font-face Roboto bằng font-display: swap + fallback là BlinkMacSystemFont, 'Segoe UI';
– Đặt line-height: 1.35 chung cho cả hai phông;
– Preload file Roboto.woff2;
→ CLS giảm còn 0.06, FCP cải thiện 0.4s, tỷ lệ thoát giảm 11% (theo Google Analytics).
Câu hỏi thường gặp
Font-display: swap có hỗ trợ trên mọi trình duyệt?
Không. font-display được hỗ trợ đầy đủ trên Chrome 60+, Firefox 60+, Edge 79+, Opera 47+. Safari bắt đầu hỗ trợ từ phiên bản 11.1 (iOS 11.3), nhưng vẫn có giới hạn với một số giá trị như optional. Với Safari cũ hơn, trình duyệt sẽ bỏ qua thuộc tính và dùng hành vi mặc định.
Có nên dùng font-display: swap cho tất cả phông chữ?
Không. Chỉ nên dùng cho phông chính, dễ đọc và có kích thước nhỏ. Với phông icon (như Font Awesome), phông trang trí hoặc phông chỉ dùng ở footer, nên dùng fallback hoặc optional để tránh swap không cần thiết. Việc lạm dụng swap có thể làm tăng số lần repaint và ảnh hưởng đến hiệu năng trên thiết bị yếu.
Font Display Swapping có ảnh hưởng đến khả năng đọc hiểu của người dùng?
Có thể ảnh hưởng nếu sự thay đổi phông gây nhảy dòng, co giãn đoạn văn hoặc làm mất dấu câu (do khác biệt glyph). Tuy nhiên, nếu chọn fallback font kỹ lưỡng và kiểm soát line-height, font-size — tác động gần như không đáng kể. Một số nghiên cứu UX (Web Almanac 2023) cho thấy người dùng không nhận ra swap nếu thời gian chờ dưới 300ms và độ chênh lệch chiều cao dòng dưới 5%.