Các phương pháp hay nhất về phông chữ

Tối ưu hoá phông chữ cho Các chỉ số quan trọng về trang web.

Katie Hempenius
Katie Hempenius

Bài viết này thảo luận các phương pháp hay nhất về hiệu suất cho phông chữ. Có nhiều cách mà phông chữ trên web ảnh hưởng đến hiệu suất:

Bài viết này được chia thành ba phần: tải phông chữ, phân phối phông chữhiển thị phông chữ. Mỗi phần giải thích cách hoạt động của khía cạnh cụ thể đó của vòng đời phông chữ và cung cấp các phương pháp hay nhất tương ứng.

Đang tải phông chữ

Phông chữ thường là tài nguyên quan trọng, vì nếu không có tài nguyên này, người dùng có thể không xem được nội dung trang. Do đó, các phương pháp hay nhất để tải phông chữ thường tập trung vào việc đảm bảo phông chữ được tải sớm nhất có thể. Bạn nên đặc biệt chú ý đến các phông chữ được tải từ trang web của bên thứ ba vì việc tải các tệp phông chữ này xuống đòi hỏi phải có thiết lập kết nối riêng biệt.

Nếu bạn không chắc liệu phông chữ trên trang của mình có được yêu cầu kịp thời hay không, hãy xem thẻ Thời gian trong bảng Mạng trong Công cụ của Chrome cho nhà phát triển để biết thêm thông tin.

Ảnh chụp màn hình thẻ Thời gian trong Công cụ cho nhà phát triển

Tìm hiểu về @font-face

Trước khi tìm hiểu các phương pháp hay nhất để tải phông chữ, bạn cần hiểu cách @font-face hoạt động và ảnh hưởng của chế độ này đến việc tải phông chữ.

Phần khai báo @font-face là một phần thiết yếu khi làm việc với mọi phông chữ web. Ít nhất, trình phân tích cú pháp khai báo tên sẽ được dùng để tham chiếu đến phông chữ và cho biết vị trí của tệp phông chữ tương ứng.

@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}

Một quan niệm sai lầm phổ biến là phông chữ được yêu cầu khi khai báo @font-face – điều này không đúng. Bản thân việc khai báo @font-face không kích hoạt thao tác tải phông chữ xuống. Thay vào đó, phông chữ chỉ được tải xuống nếu phông chữ đó được tham chiếu bằng kiểu được sử dụng trên trang. Ví dụ như sau:

@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}

h1 {
  font-family: "Open Sans"
}

Nói cách khác, trong ví dụ trên, Open Sans chỉ được tải xuống nếu trang chứa phần tử <h1>.

Do đó, khi nghĩ về việc tối ưu hoá phông chữ, điều quan trọng là bạn phải xem xét biểu định kiểu giống như chính tệp phông chữ. Việc thay đổi nội dung hoặc phân phối biểu định kiểu có thể có tác động đáng kể đến thời điểm phông chữ xuất hiện. Tương tự, việc xoá CSS không sử dụng và chia tách biểu định kiểu có thể làm giảm số lượng phông chữ mà một trang tải.

Nội dung khai báo phông chữ cùng dòng

Hầu hết các trang web sẽ được hưởng lợi rất nhiều từ việc khai báo phông chữ cùng dòng và các kiểu quan trọng khác trong <head> của tài liệu chính thay vì đưa chúng vào biểu định kiểu bên ngoài. Điều này cho phép trình duyệt khám phá các khai báo phông chữ sớm hơn vì trình duyệt không cần phải đợi biểu định kiểu bên ngoài tải xuống.

<head>
  <style>
    @font-face {
        font-family: "Open Sans";
        src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
    }

    body {
        font-family: "Open Sans";
    }

    ...etc.

  </style>
</head>

Việc chèn CSS quan trọng có thể là một kỹ thuật nâng cao hơn mà không phải trang web nào cũng có thể sử dụng. Lợi ích về hiệu suất là rõ ràng, nhưng điều này đòi hỏi các quy trình và công cụ xây dựng bổ sung để đảm bảo CSS nhất thiết và lý tưởng nhất là chỉ CSS quan trọng được hiển thị chính xác và mọi CSS bổ sung được phân phối theo phương thức chặn không hiển thị.

Kết nối trước với các nguồn gốc quan trọng của bên thứ ba

Nếu trang web của bạn tải phông chữ từ một trang web của bên thứ ba, bạn nên sử dụng gợi ý về tài nguyên preconnect để thiết lập(các) mối kết nối sớm với trang web của bên thứ ba đó. Các gợi ý về tài nguyên phải được đặt trong <head> của tài liệu. Gợi ý tài nguyên dưới đây giúp thiết lập kết nối để tải biểu định kiểu phông chữ.

<head>
  <link rel="preconnect" href="https://fonts.com">
</head>

Để kết nối trước kết nối được dùng để tải tệp phông chữ xuống, hãy thêm một gợi ý riêng về tài nguyên preconnect sử dụng thuộc tính crossorigin. Không giống như biểu định kiểu, các tệp phông chữ phải được gửi qua kết nối CORS.

<head>
  <link rel="preconnect" href="https://fonts.com">
  <link rel="preconnect" href="https://fonts.com" crossorigin>
</head>

Khi sử dụng gợi ý tài nguyên preconnect, hãy lưu ý rằng trình cung cấp phông chữ có thể phân phát biểu định kiểu và phông chữ từ các nguồn gốc riêng biệt. Ví dụ: đây là cách sử dụng gợi ý tài nguyên preconnect cho Google Fonts.

<head>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
</head>

Hãy thận trọng khi sử dụng preload để tải phông chữ

Mặc dù preload có hiệu quả cao trong việc giúp người dùng dễ dàng tìm thấy phông chữ ngay từ đầu quá trình tải trang, nhưng điều này đi kèm với cái giá là lấy đi tài nguyên của trình duyệt khi tải các tài nguyên khác.

Sử dụng phần khai báo phông chữ cùng dòng và điều chỉnh biểu định kiểu có thể là phương pháp hiệu quả hơn. Những điều chỉnh này tiến gần hơn đến việc giải quyết căn nguyên của những phông chữ mới được phát hiện, thay vì chỉ đưa ra một giải pháp.

Ngoài ra, bạn cũng nên sử dụng preload làm chiến lược tải phông chữ một cách cẩn thận vì chiến lược này bỏ qua một số chiến lược thương lượng nội dung tích hợp của trình duyệt. Ví dụ: preload bỏ qua các nội dung khai báo unicode-range. Nếu bạn nên thận trọng, bạn chỉ nên dùng để tải một định dạng phông chữ duy nhất.

Tuy nhiên, khi sử dụng biểu định kiểu bên ngoài, việc tải trước phông chữ quan trọng nhất có thể rất hiệu quả vì sau này trình duyệt sẽ không phát hiện xem phông chữ có cần thiết hay không.

Phân phối phông chữ

Phân phối phông chữ nhanh hơn mang lại kết xuất văn bản nhanh hơn. Ngoài ra, nếu phông chữ được phân phối đủ sớm, điều này có thể giúp loại bỏ những thay đổi về bố cục do hoán đổi phông chữ.

Sử dụng phông chữ tự lưu trữ

Trên giấy tờ, việc sử dụng phông chữ tự lưu trữ sẽ mang lại hiệu suất tốt hơn vì loại bỏ hoàn toàn việc thiết lập kết nối với bên thứ ba. Tuy nhiên, trên thực tế, sự khác biệt về hiệu suất giữa hai lựa chọn này chưa rõ ràng: ví dụ: Web Almanac nhận thấy rằng các trang web sử dụng phông chữ của bên thứ ba có tốc độ hiển thị nhanh hơn so với phông chữ sử dụng phông chữ của bên thứ nhất.

Nếu bạn đang xem xét việc sử dụng phông chữ tự lưu trữ, hãy xác nhận rằng trang web của bạn đang sử dụng Mạng phân phối nội dung (CDN)HTTP/2. Nếu không sử dụng những công nghệ này, ít có khả năng phông chữ tự lưu trữ sẽ mang lại hiệu suất tốt hơn. Để biết thêm thông tin, hãy xem bài viết về Mạng phân phối nội dung.

Nếu sử dụng phông chữ tự lưu trữ, bạn cũng nên áp dụng một số tính năng tối ưu hoá tệp phông chữ mà nhà cung cấp phông chữ bên thứ ba thường tự động cung cấp, ví dụ: chế độ cài đặt phụ phông chữ và nén WOFF2. Mức độ nỗ lực cần thiết để áp dụng các biện pháp tối ưu hoá này sẽ tuỳ thuộc phần nào vào những ngôn ngữ mà trang web của bạn hỗ trợ. Cụ thể, hãy lưu ý rằng việc tối ưu hoá phông chữ cho ngôn ngữ CJK có thể đặc biệt khó khăn.

Sử dụng WOFF2

Trong số các phông chữ hiện đại, WOFF2 là phông chữ mới nhất, hỗ trợ trình duyệt rộng nhất và có khả năng nén tốt nhất. Vì sử dụng Brotli, WOFF2 nén tốt hơn 30% so với WOFF, dẫn đến việc tải ít dữ liệu hơn và do đó hiệu suất nhanh hơn.

Do trình duyệt hỗ trợ, các chuyên gia hiện khuyên bạn chỉ nên sử dụng WOFF2:

Trên thực tế, chúng tôi cho rằng cũng đã đến lúc tuyên bố rằng: Chỉ sử dụng WOFF2 và quên mọi thứ khác.

Việc này sẽ giúp đơn giản hoá rất nhiều CSS và quy trình công việc, đồng thời tránh được trường hợp vô tình tải hai lần hoặc có phông chữ không chính xác xuống. WOFF2 hiện được hỗ trợ ở mọi nơi. Vì vậy, trừ khi bạn cần hỗ trợ các trình duyệt thực sự cổ xưa, chỉ cần sử dụng WOFF2. Nếu bạn không thể, hãy xem xét không phân phối bất kỳ phông chữ nào trên web cho các trình duyệt cũ hơn đó. Điều này sẽ không thành vấn đề nếu bạn có sẵn một chiến lược dự phòng hiệu quả. Khách truy cập sử dụng các trình duyệt cũ hơn sẽ chỉ thấy phông chữ dự phòng của bạn.

Bram Stein, theo Niên giám web 2022

Phông chữ tập hợp con

Tệp phông chữ thường chứa một số lượng lớn ký tự cho tất cả các ký tự được hỗ trợ. Tuy nhiên, bạn có thể không cần tất cả các ký tự trên trang và có thể giảm kích thước của tệp phông chữ bằng cách đặt phông chữ thay thế.

Chỉ số mô tả unicode-range trong phần khai báo @font-face sẽ thông báo cho trình duyệt biết có thể sử dụng ký tự nào cho phông chữ.

@font-face {
    font-family: "Open Sans";
    src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
    unicode-range: U+0025-00FF;
}

Hệ thống sẽ tải một tệp phông chữ xuống nếu trang chứa một hoặc nhiều ký tự khớp với dải ô unicode. unicode-range thường dùng để phân phát nhiều tệp phông chữ tuỳ thuộc vào ngôn ngữ dùng trong nội dung trang.

unicode-range thường được dùng kết hợp với kỹ thuật đặt phụ. Phông chữ tập con bao gồm một phần nhỏ hơn của ký tự có trong tệp phông chữ gốc. Ví dụ: thay vì cung cấp tất cả ký tự cho tất cả người dùng, một trang web có thể tạo phông chữ tập hợp con riêng biệt cho các ký tự Latinh và Chữ Kirin. Số lượng ký tự trên mỗi phông chữ thay đổi rất nhiều: phông chữ Latinh thường có độ lớn từ 100 đến 1000 glyphs mỗi phông chữ; phông chữ CJK có thể có hơn 10.000 ký tự. Việc xoá những ký tự không dùng đến có thể làm giảm đáng kể kích thước tệp của phông chữ.

Một số nhà cung cấp phông chữ có thể tự động cung cấp các phiên bản tệp phông chữ khác nhau với các tập hợp con khác nhau. Ví dụ: Google Fonts thực hiện việc này theo mặc định:

/* devanagari */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJbecnFHGPezSQ.woff2) format('woff2');
  unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
}
/* latin-ext */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJnecnFHGPezSQ.woff2) format('woff2');
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJfecnFHGPc.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

Khi chuyển sang tự lưu trữ, đây là một hoạt động tối ưu hoá có thể dễ bị bỏ lỡ và dẫn đến các tệp phông chữ lớn hơn trên máy.

Bạn cũng có thể phân nhóm phông chữ theo cách thủ công nếu nhà cung cấp phông chữ cho phép việc này thông qua API (Google Fonts hỗ trợ việc này bằng cách cung cấp tham số text) hoặc bằng cách chỉnh sửa các tệp phông chữ theo cách thủ công rồi tự lưu trữ. Các công cụ tạo tập hợp con phông chữ bao gồm phông chữ phụglyphanger. Tuy nhiên, hãy kiểm tra giấy phép của phông chữ mà bạn sử dụng cho phép cài đặt phụ và tự lưu trữ.

Sử dụng ít phông chữ hơn

Phông chữ nhanh nhất để phân phối là phông chữ chưa được yêu cầu ngay từ đầu. Phông chữ hệ thống và phông chữ biến đổi là hai cách có thể giúp giảm số lượng phông chữ trên web được dùng trên trang web của bạn.

Phông chữ hệ thống là phông chữ mặc định được sử dụng trong giao diện người dùng trên thiết bị của người dùng. Phông chữ hệ thống thường khác nhau tuỳ theo hệ điều hành và phiên bản. Vì phông chữ đã được cài đặt, bạn không cần tải xuống phông chữ này. Phông chữ hệ thống có thể hoạt động đặc biệt hiệu quả với văn bản nội dung.

Để sử dụng phông chữ hệ thống trong CSS, hãy liệt kê system-ui làm bộ phông chữ:

font-family: system-ui

Ý tưởng đằng sau phông chữ thay đổi là một phông chữ thay đổi có thể dùng để thay thế cho nhiều tệp phông chữ. Phông chữ có thể thay đổi hoạt động bằng cách xác định kiểu phông chữ "mặc định" và cung cấp "các trục" để thao tác với phông chữ. Ví dụ: Bạn có thể dùng một phông chữ thay đổi có trục Weight để triển khai chữ mà trước đây yêu cầu phông chữ riêng biệt cho sáng, thường, đậm và đậm hơn.

Không phải ai cũng hữu ích từ việc chuyển sang sử dụng nhiều phông chữ thay đổi. Phông chữ thay đổi chứa nhiều kiểu, vì vậy thường có kích thước tệp lớn hơn so với các phông chữ riêng lẻ không biến đổi chỉ chứa một kiểu. Các trang web sẽ nhận thấy sự cải thiện lớn nhất từ việc sử dụng phông chữ biến đổi là những trang web sử dụng (và cần sử dụng) nhiều kiểu phông chữ và độ đậm.

Kết xuất phông chữ

Khi có phông chữ web chưa được tải, trình duyệt gặp phải một tình huống khó xử: liệu trình duyệt có nên trì hoãn hiển thị văn bản cho đến khi phông chữ web đã có không? Hay ứng dụng có nên hiển thị văn bản bằng phông chữ dự phòng cho đến khi phông chữ trên web đến không?

Các trình duyệt khác nhau sẽ xử lý trường hợp này theo cách khác nhau. Theo mặc định, các trình duyệt dựa trên Chromium và Firefox sẽ chặn hiển thị văn bản trong tối đa 3 giây nếu phông chữ web được liên kết không được tải; Safari sẽ chặn hiển thị văn bản vô thời hạn.

Bạn có thể định cấu hình hành vi này bằng cách sử dụng thuộc tính font-display. Lựa chọn này có thể mang lại những ý nghĩa quan trọng: font-display có khả năng ảnh hưởng đến LCP, FCP và độ ổn định của bố cục.

Chọn chiến lược font-display thích hợp

font-display thông báo cho trình duyệt cách tiếp tục hiển thị văn bản khi phông chữ web liên quan chưa tải. Kiểu chữ này được xác định theo mỗi kiểu phông chữ.

@font-face {
  font-family: Roboto, Sans-Serif
  src: url(/fonts/roboto.woff) format('woff'),
  font-display: swap;
}

Có thể có năm giá trị cho font-display:

Giá trị Khoảng thời gian chặn Hoán đổi khoảng thời gian
Tự động Thay đổi tuỳ theo trình duyệt Thay đổi tuỳ theo trình duyệt
Chặn 2–3 giây Vô hạn
Hoán đổi 0 mili giây Vô hạn
Dự phòng 100 mili giây 3 giây
Không bắt buộc 100 mili giây Không có
  • Thời gian chặn: Khoảng thời gian chặn bắt đầu khi trình duyệt yêu cầu phông chữ trên web. Trong thời gian chặn, nếu phông chữ trên web không có sẵn, thì phông chữ đó sẽ hiển thị bằng phông chữ dự phòng ẩn và do đó, người dùng sẽ không nhìn thấy văn bản đó. Nếu không có phông chữ nào vào cuối khoảng thời gian chặn, thì phông chữ đó sẽ được hiển thị bằng phông chữ dự phòng.
  • Khoảng thời gian hoán đổi: Khoảng thời gian hoán đổi diễn ra sau khoảng thời gian chặn. Nếu phông chữ trên web có sẵn trong khoảng thời gian hoán đổi, phông chữ đó sẽ được "hoán đổi".

Chiến lược font-display phản ánh nhiều quan điểm về sự đánh đổi giữa hiệu suất và tính thẩm mỹ. Do đó, rất khó để đưa ra một phương pháp đề xuất vì nó phụ thuộc vào sở thích cá nhân, tầm quan trọng của phông chữ trên web đối với trang và thương hiệu, cũng như mức độ khó chịu của phông chữ đến muộn khi hoán đổi.

Đối với hầu hết các trang web, đây là 3 chiến lược sẽ phù hợp nhất:

  • Nếu hiệu suất là ưu tiên hàng đầu: Hãy sử dụng font-display: optional. Đây là cách tiếp cận "hiệu quả" nhất: việc hiển thị văn bản bị trì hoãn không quá 100 mili giây và chúng tôi đảm bảo rằng sẽ không có những thay đổi về bố cục liên quan đến hoán đổi phông chữ. Tuy nhiên, nhược điểm ở đây là phông chữ trên web sẽ không được sử dụng nếu gửi muộn.

  • Nếu việc hiển thị nhanh văn bản là ưu tiên hàng đầu, nhưng bạn vẫn muốn đảm bảo phông chữ trên web được sử dụng: Hãy sử dụng font-display: swap nhưng đảm bảo phân phối phông chữ đủ sớm để không làm thay đổi bố cục. Nhược điểm của tuỳ chọn này là sự thay đổi gây khó chịu khi phông chữ đến trễ.

  • Nếu việc đảm bảo văn bản hiển thị bằng phông chữ trên web là một ưu tiên hàng đầu: Hãy sử dụng font-display: block nhưng nhớ cung cấp phông chữ đủ sớm để giảm thiểu độ trễ của văn bản. Nhược điểm của việc này là việc hiển thị văn bản ban đầu sẽ bị trễ. Lưu ý rằng mặc dù việc gỡ bỏ này, nó vẫn có thể gây ra sự thay đổi bố cục vì văn bản thực sự được vẽ không hiển thị và do đó, không gian phông chữ dự phòng được dùng để đặt trước không gian. Sau khi tải phông chữ trên web, phông chữ này có thể cần đến một không gian khác biệt, do đó sẽ tạo ra sự thay đổi. Tuy nhiên, đây có thể là một sự thay đổi ít gây khó chịu hơn so với font-display: swap vì bản thân văn bản sẽ không được chuyển đổi.

Ngoài ra, hãy nhớ rằng có thể kết hợp 2 cách tiếp cận này: chẳng hạn như sử dụng font-display: swap cho các thành phần thương hiệu và các thành phần trang khác biệt về mặt hình ảnh; sử dụng font-display: optional cho các phông chữ được dùng trong văn bản nội dung.

Giảm sự thay đổi giữa phông chữ dự phòng và phông chữ web

Để giảm tác động đến CLS, bạn có thể sử dụng các thuộc tính size-adjust mới. Để biết thêm thông tin, hãy xem bài viết về CSS size-adjust. Đây là một tính năng bổ sung rất mới cho bộ công cụ của chúng tôi, hiện đã nâng cao hơn và thủ công hơn một chút. Nhưng đó cũng là một cách mà bạn nên thử nghiệm và theo dõi để tìm ra những cải tiến về công cụ trong tương lai!

Kết luận

Phông chữ trên web vẫn là nút thắt cổ chai về hiệu suất nhưng chúng tôi có nhiều lựa chọn ngày càng tăng để cho phép chúng tôi tối ưu hoá chúng nhằm giảm nút thắt cổ chai này nhiều nhất có thể.