Kiểu chữ là yếu tố cơ bản để có được thiết kế, thương hiệu, khả năng đọc và khả năng hỗ trợ tiếp cận hiệu quả. Phông chữ trên web cho phép tất cả những điều trên và hơn thế nữa: văn bản có thể chọn, tìm kiếm, thu phóng và thân thiện với DPI cao, mang lại khả năng hiển thị văn bản nhất quán và sắc nét bất kể kích thước và độ phân giải màn hình. WebFont đóng vai trò quan trọng đối với thiết kế, trải nghiệm người dùng và hiệu suất.
Tối ưu hoá phông chữ trên web là một phần quan trọng trong chiến lược hiệu suất tổng thể. Mỗi phông chữ là một tài nguyên bổ sung và một số phông chữ có thể chặn quá trình hiển thị văn bản. Tuy nhiên, chỉ vì trang đang sử dụng WebFonts không có nghĩa là trang đó phải hiển thị chậm hơn. Ngược lại, các phông chữ được tối ưu hoá, kết hợp với một chiến lược hợp lý về cách tải và áp dụng các phông chữ đó trên trang, có thể giúp giảm tổng kích thước trang và cải thiện thời gian hiển thị trang.
Cấu trúc của phông chữ web
Phông chữ trên web là một tập hợp các ký tự, trong đó mỗi ký tự là một hình dạng vectơ mô tả một chữ cái hoặc ký hiệu. Do đó, hai biến đơn giản sẽ xác định kích thước của một tệp phông chữ cụ thể: độ phức tạp của đường dẫn vectơ của từng glyph và số lượng glyph trong một phông chữ cụ thể. Ví dụ: Open Sans là một trong những WebFont phổ biến nhất, chứa 897 glyph, bao gồm các ký tự Latinh, Hy Lạp và Cyrill.
Khi chọn phông chữ, bạn cần cân nhắc những bộ ký tự được hỗ trợ. Nếu cần bản địa hoá nội dung trang sang nhiều ngôn ngữ, bạn nên sử dụng một phông chữ có thể mang lại giao diện và trải nghiệm nhất quán cho người dùng. Ví dụ: bộ phông chữ Noto của Google hướng đến mục tiêu hỗ trợ tất cả các ngôn ngữ trên thế giới. Tuy nhiên, xin lưu ý rằng tổng kích thước của Noto, bao gồm tất cả các ngôn ngữ, sẽ là tệp ZIP có kích thước hơn 1, 1 GB.
Trong bài đăng này, bạn sẽ tìm hiểu cách giảm kích thước tệp được phân phối của phông chữ trên web.
Định dạng phông chữ trên web
Hiện có hai định dạng vùng chứa phông chữ được đề xuất đang được sử dụng trên web:
WOFF và WOFF 2.0 được hỗ trợ rộng rãi và được tất cả các trình duyệt hiện đại hỗ trợ.
- Phân phát biến thể WOFF 2.0 cho các trình duyệt hiện đại.
- Nếu thực sự cần thiết (ví dụ: nếu bạn vẫn cần hỗ trợ Internet Explorer 11), hãy phân phát WOFF làm phương án dự phòng.
- Ngoài ra, hãy cân nhắc việc không sử dụng phông chữ web cho các trình duyệt cũ và quay lại phông chữ hệ thống. Điều này cũng có thể giúp các thiết bị cũ, có nhiều hạn chế hơn hoạt động hiệu quả hơn.
- Vì WOFF và WOFF 2.0 bao gồm tất cả các cơ sở cho trình duyệt hiện đại và trình duyệt cũ vẫn đang được sử dụng, nên bạn không cần dùng EOT và TTF nữa. Việc này có thể dẫn đến thời gian tải phông chữ trên web lâu hơn.
Phông chữ trên web và tính năng nén
Cả WOFF và WOFF 2.0 đều có tính năng nén tích hợp. Tính năng nén nội bộ của WOFF 2.0 sử dụng Brotli và có khả năng nén tốt hơn tới 30% so với WOFF. Để biết thêm thông tin, hãy xem báo cáo đánh giá WOFF 2.0.
Cuối cùng, bạn cần lưu ý rằng một số định dạng phông chữ chứa siêu dữ liệu bổ sung, chẳng hạn như gợi ý phông chữ và thông tin kerning (khoảng cách giữa các chữ cái) có thể không cần thiết trên một số nền tảng, cho phép tối ưu hoá thêm kích thước tệp. Ví dụ: Google Fonts duy trì hơn 30 biến thể được tối ưu hoá cho mỗi phông chữ, đồng thời tự động phát hiện và phân phối biến thể tối ưu cho từng nền tảng và trình duyệt.
Xác định một bộ phông chữ bằng @font-face
Quy tắc @font-face CSS cho phép bạn xác định vị trí của một tài nguyên phông chữ cụ thể, đặc điểm kiểu của tài nguyên đó và các điểm mã Unicode mà tài nguyên đó sẽ được dùng. Bạn có thể dùng tổ hợp các khai báo @font-face như vậy để tạo "bộ phông chữ". Trình duyệt sẽ dùng bộ phông chữ này để đánh giá những tài nguyên phông chữ cần tải xuống và áp dụng cho trang hiện tại.
Cân nhắc sử dụng phông chữ biến đổi
Phông chữ biến đổi có thể giảm đáng kể kích thước tệp của phông chữ trong trường hợp bạn cần nhiều biến thể của một phông chữ. Thay vì phải tải các kiểu chữ thường và kiểu chữ đậm cùng với phiên bản in nghiêng của chúng, bạn có thể tải một tệp duy nhất chứa tất cả thông tin. Tuy nhiên, kích thước tệp phông chữ linh hoạt sẽ lớn hơn một biến thể phông chữ riêng lẻ, mặc dù nhỏ hơn tổ hợp của nhiều biến thể. Thay vì một phông chữ biến đổi lớn, bạn nên phân phát các biến thể phông chữ quan trọng trước, sau đó tải các biến thể khác xuống.
Tất cả trình duyệt hiện đại hiện đều hỗ trợ phông chữ có thể thay đổi. Hãy tìm hiểu thêm trong bài viết Giới thiệu về phông chữ có thể thay đổi trên web.
Chọn định dạng phù hợp
Mỗi khai báo @font-face cung cấp tên của bộ phông chữ, đóng vai trò là một nhóm logic gồm nhiều khai báo, thuộc tính phông chữ như kiểu, độ đậm và độ giãn, cũng như trình mô tả src, chỉ định danh sách vị trí được ưu tiên cho tài nguyên phông chữ.
@font-face {
font-family: 'Awesome Font';
font-style: normal;
font-weight: 400;
src: local('Awesome Font'),
url('/fonts/awesome.woff2') format('woff2'),
/* Only serve WOFF if necessary. Otherwise,
WOFF 2.0 is fine by itself. */
url('/fonts/awesome.woff') format('woff');
}
@font-face {
font-family: 'Awesome Font';
font-style: italic;
font-weight: 400;
src: local('Awesome Font Italic'),
url('/fonts/awesome-i.woff2') format('woff2'),
url('/fonts/awesome-i.woff') format('woff');
}
Trước tiên, lưu ý rằng các ví dụ trên xác định một bộ Awesome Font duy nhất với hai kiểu (bình thường và nghiêng), mỗi kiểu trỏ đến một tập hợp tài nguyên phông chữ khác nhau. Đến lượt, mỗi bộ mô tả src chứa một danh sách được ưu tiên, phân tách bằng dấu phẩy gồm các biến thể tài nguyên:
- Chỉ thị
local()cho phép bạn tham chiếu, tải và sử dụng phông chữ đã cài đặt cục bộ. Nếu người dùng đã cài đặt phông chữ trên hệ thống của họ, thì thao tác này sẽ hoàn toàn bỏ qua mạng và là thao tác nhanh nhất. - Chỉ thị
url()cho phép bạn tải các phông chữ bên ngoài và được phép chứa một gợi ýformat()không bắt buộc cho biết định dạng của phông chữ mà URL đã cung cấp tham chiếu đến.
Khi xác định rằng cần có phông chữ, trình duyệt sẽ lặp lại danh sách tài nguyên được cung cấp theo thứ tự đã chỉ định và cố gắng tải tài nguyên thích hợp. Ví dụ: theo ví dụ trên:
- Trình duyệt thực hiện bố cục trang và xác định những biến thể phông chữ cần thiết để hiển thị văn bản đã chỉ định trên trang. Trình duyệt sẽ không tải xuống những phông chữ không thuộc Mô hình đối tượng CSS (CSSOM) của trang vì không cần thiết.
- Đối với mỗi phông chữ bắt buộc, trình duyệt sẽ kiểm tra xem phông chữ đó có sẵn trên thiết bị hay không.
- Nếu phông chữ không có sẵn trên máy, trình duyệt sẽ lặp lại các định nghĩa bên ngoài:
- Nếu có một gợi ý về định dạng, trình duyệt sẽ kiểm tra xem có hỗ trợ gợi ý đó hay không trước khi bắt đầu tải xuống. Nếu trình duyệt không hỗ trợ gợi ý này, trình duyệt sẽ chuyển sang gợi ý tiếp theo.
- Nếu không có gợi ý nào về định dạng, trình duyệt sẽ tải tài nguyên xuống.
Việc kết hợp các chỉ thị cục bộ và chỉ thị bên ngoài với các gợi ý thích hợp về định dạng cho phép bạn chỉ định tất cả các định dạng phông chữ có sẵn và để trình duyệt xử lý phần còn lại. Trình duyệt sẽ xác định những tài nguyên cần thiết và chọn định dạng tối ưu.
Chia nhỏ phạm vi Unicode
Ngoài các thuộc tính phông chữ như kiểu, độ đậm và độ giãn, quy tắc @font-face còn cho phép bạn xác định một tập hợp các điểm mã Unicode mà mỗi tài nguyên hỗ trợ. Điều này cho phép bạn chia một phông chữ Unicode lớn thành các tập hợp con nhỏ hơn (ví dụ: tập hợp con Latinh, Cyrillic và Hy Lạp) và chỉ tải xuống những glyph cần thiết để hiển thị văn bản trên một trang cụ thể.
Bộ mô tả unicode-range cho phép bạn chỉ định một danh sách các giá trị phạm vi được phân tách bằng dấu phẩy, mỗi giá trị có thể ở một trong ba dạng sau:
- Một điểm mã (ví dụ:
U+416) - Phạm vi khoảng (ví dụ:
U+400-4ff): cho biết điểm mã bắt đầu và kết thúc của một phạm vi - Phạm vi ký tự đại diện (ví dụ:
U+4??): Ký tự?cho biết mọi chữ số thập lục phân
Ví dụ: bạn có thể chia họ Awesome Font thành các tập hợp con Latinh và Nhật Bản, mỗi tập hợp con mà trình duyệt tải xuống khi cần:
@font-face {
font-family: 'Awesome Font';
font-style: normal;
font-weight: 400;
src: local('Awesome Font'),
url('/fonts/awesome-l.woff2') format('woff2');
/* Latin glyphs */
unicode-range: U+000-5FF;
}
@font-face {
font-family: 'Awesome Font';
font-style: normal;
font-weight: 400;
src: local('Awesome Font'),
url('/fonts/awesome-jp.woff2') format('woff2');
/* Japanese glyphs */
unicode-range: U+3000-9FFF, U+ff??;
}
Việc sử dụng các tập hợp con của dải Unicode và các tệp riêng biệt cho từng biến thể kiểu chữ của phông chữ cho phép bạn xác định một bộ phông chữ kết hợp có tốc độ tải xuống nhanh hơn và hiệu quả hơn. Khách truy cập chỉ tải những biến thể và tập hợp con mà họ cần, đồng thời họ không bắt buộc phải tải những tập hợp con mà họ có thể không bao giờ thấy hoặc sử dụng trên trang.
Hầu hết các trình duyệt đều hỗ trợ unicode-range. Để tương thích với các trình duyệt cũ, bạn có thể cần quay lại "phân nhóm thủ công". Trong trường hợp này, bạn phải quay lại cung cấp một tài nguyên phông chữ duy nhất chứa tất cả các tập hợp con cần thiết và ẩn phần còn lại khỏi trình duyệt. Ví dụ: nếu trang chỉ sử dụng các ký tự Latinh, thì bạn có thể loại bỏ các glyph khác và phân phát tập hợp con cụ thể đó dưới dạng một tài nguyên độc lập.
- Xác định những tập hợp con cần thiết:
- Nếu trình duyệt hỗ trợ tính năng chia nhỏ unicode-range, thì trình duyệt sẽ tự động chọn đúng tập hợp con. Trang này chỉ cần cung cấp các tệp con và chỉ định các phạm vi unicode thích hợp trong các quy tắc
@font-face. - Nếu trình duyệt không hỗ trợ việc chia nhỏ unicode-range, thì trang cần ẩn tất cả các tập hợp con không cần thiết; tức là nhà phát triển phải chỉ định các tập hợp con bắt buộc.
- Nếu trình duyệt hỗ trợ tính năng chia nhỏ unicode-range, thì trình duyệt sẽ tự động chọn đúng tập hợp con. Trang này chỉ cần cung cấp các tệp con và chỉ định các phạm vi unicode thích hợp trong các quy tắc
- Tạo tập hợp con của phông chữ:
- Sử dụng công cụ pyftsubset mã nguồn mở để tạo tập hợp con và tối ưu hoá phông chữ.
- Theo mặc định, một số máy chủ phông chữ (chẳng hạn như Google Fonts) sẽ tự động tạo tập hợp con.
- Một số dịch vụ phông chữ cho phép tạo tập hợp con theo cách thủ công thông qua các tham số truy vấn tuỳ chỉnh. Bạn có thể dùng các tham số này để chỉ định tập hợp con bắt buộc cho trang của mình theo cách thủ công. Tham khảo tài liệu của nhà cung cấp phông chữ.
Lựa chọn và tổng hợp phông chữ
Mỗi bộ phông chữ có thể bao gồm nhiều biến thể về kiểu chữ (thường, đậm, nghiêng) và nhiều độ đậm cho mỗi kiểu chữ. Mỗi glyph có thể chứa các hình dạng rất khác nhau – ví dụ: khoảng cách, kích thước hoặc hình dạng hoàn toàn khác.
Sơ đồ trên minh hoạ một họ phông chữ có 3 độ đậm khác nhau:
- 400 (thường).
- 700 (đậm).
- 900 (siêu đậm).
Tất cả các biến thể trung gian khác (được biểu thị bằng màu xám) đều được trình duyệt tự động liên kết với biến thể gần nhất.
Khi bạn chỉ định một trọng số mà không có khuôn mặt nào, thì một khuôn mặt có trọng số gần đó sẽ được dùng. Nhìn chung, các trọng lượng đậm sẽ tương ứng với các khuôn mặt có trọng lượng lớn hơn và các trọng lượng nhạt sẽ tương ứng với các khuôn mặt có trọng lượng nhỏ hơn.
Thuật toán so khớp phông chữ CSS
Logic tương tự cũng áp dụng cho các biến thể in nghiêng. Nhà thiết kế phông chữ kiểm soát những biến thể mà họ sẽ tạo ra, còn bạn kiểm soát những biến thể mà bạn sẽ sử dụng trên trang. Vì mỗi biến thể là một tệp tải xuống riêng biệt, nên bạn nên giữ số lượng biến thể ở mức thấp. Ví dụ: bạn có thể xác định 2 biến thể đậm cho họ Awesome Font:
@font-face {
font-family: 'Awesome Font';
font-style: normal;
font-weight: 400;
src: local('Awesome Font'),
url('/fonts/awesome-l.woff2') format('woff2');
/* Latin glyphs */
unicode-range: U+000-5FF;
}
@font-face {
font-family: 'Awesome Font';
font-style: normal;
font-weight: 700;
src: local('Awesome Font'),
url('/fonts/awesome-l-700.woff2') format('woff2');
/* Latin glyphs */
unicode-range: U+000-5FF;
}
Ví dụ trên khai báo họ Awesome Font bao gồm 2 tài nguyên bao gồm cùng một bộ ký tự Latinh (U+000-5FF) nhưng cung cấp 2 "trọng số" khác nhau: bình thường (400) và đậm (700). Tuy nhiên, điều gì sẽ xảy ra nếu một trong các quy tắc CSS của bạn chỉ định một độ đậm phông chữ khác hoặc đặt thuộc tính font-style thành italic?
- Nếu không có phông chữ trùng khớp hoàn toàn, trình duyệt sẽ thay thế bằng phông chữ gần giống nhất.
- Nếu không tìm thấy kiểu chữ nào phù hợp (ví dụ: không có biến thể chữ nghiêng nào được khai báo trong ví dụ trên), thì trình duyệt sẽ tự tổng hợp biến thể phông chữ.
Ví dụ trên minh hoạ sự khác biệt giữa kết quả thực tế và kết quả phông chữ được tổng hợp cho Open Sans. Tất cả các biến thể được tổng hợp đều được tạo từ một phông chữ có trọng lượng 400. Như bạn có thể thấy, có sự khác biệt đáng kể trong kết quả. Không có thông tin chi tiết về cách tạo các biến thể in đậm và nghiêng. Do đó, kết quả sẽ khác nhau tuỳ theo trình duyệt và phụ thuộc nhiều vào phông chữ.
Danh sách kiểm tra việc tối ưu hoá cỡ chữ trên web
- Kiểm tra và giám sát việc sử dụng phông chữ: đừng sử dụng quá nhiều phông chữ trên các trang của bạn và đối với mỗi phông chữ, hãy giảm thiểu số lượng biến thể được sử dụng. Điều này giúp mang lại trải nghiệm nhất quán và nhanh chóng hơn cho người dùng.
- Tránh sử dụng các định dạng cũ nếu có thể: Các định dạng EOT, TTF và WOFF có kích thước lớn hơn WOFF 2.0. EOT và TTF là những định dạng hoàn toàn không cần thiết, trong khi WOFF có thể chấp nhận được nếu bạn cần hỗ trợ Internet Explorer 11. Nếu bạn chỉ nhắm đến các trình duyệt hiện đại, thì chỉ sử dụng WOFF 2.0 là lựa chọn đơn giản và hiệu quả nhất.
- Tạo tập hợp con cho tài nguyên phông chữ: nhiều phông chữ có thể được tạo tập hợp con hoặc chia thành nhiều unicode-range để chỉ phân phối những glyph mà một trang cụ thể yêu cầu. Điều này giúp giảm kích thước tệp và cải thiện tốc độ tải xuống tài nguyên. Tuy nhiên, khi xác định các tập hợp con, hãy cẩn thận để tối ưu hoá việc sử dụng lại phông chữ. Ví dụ: không tải một bộ ký tự khác nhưng trùng lặp trên mỗi trang. Cách hay là chia thành các nhóm nhỏ dựa trên chữ viết: ví dụ: chữ Latinh và chữ Cyrillic.
- Ưu tiên
local()trong danh sáchsrccủa bạn: việc liệt kêlocal('Font Name')trước tiên trong danh sáchsrcđảm bảo rằng các yêu cầu HTTP không được thực hiện cho những phông chữ đã được cài đặt. - Sử dụng Lighthouse để kiểm tra hoạt động nén văn bản.
Ảnh hưởng đến Nội dung lớn nhất hiển thị (LCP) và Mức thay đổi bố cục tích luỹ (CLS)
Tuỳ thuộc vào nội dung trên trang của bạn, các nút văn bản có thể được coi là những thành phần tiềm năng cho Nội dung lớn nhất hiển thị (LCP). Do đó, bạn cần đảm bảo phông chữ trên web có kích thước nhỏ nhất có thể bằng cách làm theo lời khuyên trong bài viết này để người dùng có thể nhìn thấy văn bản trên trang của bạn càng sớm càng tốt.
Nếu bạn lo ngại rằng mặc dù bạn đã nỗ lực tối ưu hoá nhưng văn bản trên trang có thể mất quá nhiều thời gian để xuất hiện do tài nguyên phông chữ web lớn, thì thuộc tính font-display có một số chế độ cài đặt có thể giúp bạn tránh văn bản không hiển thị trong khi phông chữ đang tải xuống. Tuy nhiên, việc sử dụng giá trị swap có thể gây ra những thay đổi đáng kể về bố cục, ảnh hưởng đến Mức thay đổi bố cục tích luỹ (CLS) của trang web. Hãy cân nhắc sử dụng giá trị optional hoặc fallback nếu có thể.
Nếu phông chữ trên web là yếu tố quan trọng đối với việc xây dựng thương hiệu (và do đó, cả trải nghiệm người dùng), hãy cân nhắc việc tải trước phông chữ để trình duyệt có thể bắt đầu yêu cầu phông chữ sớm hơn. Điều này có thể làm giảm cả khoảng thời gian hoán đổi nếu bạn sử dụng font-display: swap hoặc khoảng thời gian chặn nếu bạn không sử dụng font-display.