Cải thiện Thời gian hiển thị nội dung lớn nhất trên hệ sinh thái JavaScript.
Trong dự án Aurora, Google đã làm việc với các khung web phổ biến để đảm bảo chúng hoạt động hiệu quả theo Chỉ số quan trọng chính của trang web. Angular và Next.js đã ra mắt tính năng cùng dòng phông chữ, được giải thích trong phần đầu của bài viết này. Cách tối ưu hoá thứ hai mà chúng tôi sẽ đề cập là nội tuyến CSS quan trọng, hiện được bật theo mặc định trong Angular CLI và đang trong quá trình triển khai trong Nuxt.js.
Nội tuyến phông chữ
Sau khi phân tích hàng trăm ứng dụng, nhóm Aurora nhận thấy rằng các nhà phát triển thường đưa phông chữ vào ứng dụng bằng cách tham chiếu phông chữ trong phần tử <head>
của index.html
. Sau đây là ví dụ về giao diện của ứng dụng khi thêm biểu tượng Material:
<!doctype html>
<html lang="en">
<head>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
...
</html>
Mặc dù mẫu này hoàn toàn hợp lệ và có chức năng, nhưng mẫu này chặn quá trình kết xuất của ứng dụng và đưa ra một yêu cầu bổ sung. Để hiểu rõ hơn về những gì đang diễn ra, hãy xem mã nguồn của tệp kiểu được tham chiếu trong HTML ở trên:
/* fallback */
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/font.woff2) format('woff2');
}
.material-icons {
/*...*/
}
Hãy lưu ý cách định nghĩa font-face
tham chiếu đến một tệp bên ngoài được lưu trữ trên fonts.gstatic.com
.
Khi tải ứng dụng, trước tiên, trình duyệt phải tải tệp kiểu ban đầu được tham chiếu trong phần đầu.
Tiếp theo, trình duyệt sẽ tải tệp woff2
xuống, sau đó có thể tiếp tục hiển thị ứng dụng.
Bạn có thể tối ưu hoá bằng cách tải biểu định kiểu ban đầu xuống tại thời điểm tạo bản dựng rồi đưa biểu định kiểu đó vào cùng dòng trong index.html
. Thao tác này sẽ bỏ qua toàn bộ lượt truy cập đến CDN trong thời gian chạy, giúp giảm thời gian chặn.
Khi tạo ứng dụng, một yêu cầu sẽ được gửi đến CDN. Thao tác này sẽ tìm nạp biểu định kiểu và đưa biểu định kiểu vào cùng dòng trong tệp HTML, thêm <link rel=preconnect>
vào miền. Áp dụng kỹ thuật này, chúng tôi sẽ nhận được kết quả sau:
<!doctype html>
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin >
<style type="text/css">
@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/font.woff2) format('woff2');}.material-icons{/*...*/}</style>
...
</html>
Tính năng cùng dòng phông chữ hiện có trong Next.js và Angular
Khi triển khai tính năng tối ưu hoá trong công cụ cơ bản, các nhà phát triển khung sẽ giúp các ứng dụng hiện có và ứng dụng mới dễ dàng kích hoạt tính năng đó, qua đó cải thiện toàn bộ hệ sinh thái.
Tính năng cải tiến này được bật theo mặc định từ Next.js phiên bản 10.2 và Angular phiên bản 11. Cả hai đều hỗ trợ sử dụng cùng dòng phông chữ của Google và Adobe. Angular dự kiến sẽ ra mắt phiên bản sau trong phiên bản 12.2.
Bạn có thể tìm thấy cách triển khai đưa phông chữ vào cùng dòng trong Next.js trên GitHub và xem video giải thích cách tối ưu hoá này trong ngữ cảnh của Angular.
Nhúng CSS quan trọng
Một điểm cải tiến khác là cải thiện các chỉ số Hiển thị nội dung đầu tiên (FCP) và Thời gian hiển thị nội dung lớn nhất (LCP) bằng cách nội tuyến CSS quan trọng. CSS quan trọng của một trang bao gồm tất cả kiểu được sử dụng khi hiển thị ban đầu. Để tìm hiểu thêm về chủ đề này, hãy xem bài viết Trì hoãn CSS không quan trọng.
Chúng tôi nhận thấy nhiều ứng dụng đang tải các kiểu đồng bộ, điều này chặn quá trình kết xuất ứng dụng. Cách khắc phục nhanh chóng là tải các kiểu không đồng bộ. Thay vì tải tập lệnh bằng media="all"
, hãy đặt giá trị của thuộc tính media
thành print
và sau khi tải xong, hãy thay thế giá trị thuộc tính thành all
:
<link rel="stylesheet" href="..." media="print" onload="this.media='all'">
Tuy nhiên, phương pháp này có thể gây ra hiện tượng nhấp nháy nội dung không được định kiểu.
Video ở trên cho thấy quá trình kết xuất một trang, trang này tải các kiểu của trang một cách không đồng bộ. Tình trạng nhấp nháy xảy ra vì trình duyệt bắt đầu tải các kiểu xuống trước rồi hiển thị HTML tiếp theo. Sau khi tải các kiểu xuống, trình duyệt sẽ kích hoạt sự kiện onload
của phần tử đường liên kết, cập nhật thuộc tính media
thành all
và áp dụng các kiểu cho DOM.
Trong khoảng thời gian từ khi hiển thị HTML đến khi áp dụng kiểu, trang sẽ không được tạo kiểu một phần. Khi trình duyệt sử dụng các kiểu, chúng tôi thấy hiện tượng nhấp nháy. Đây là trải nghiệm không tốt cho người dùng và dẫn đến hiện tượng hồi quy trong Điểm số tổng hợp về mức thay đổi bố cục (CLS).
Tính năng nội tuyến CSS quan trọng, cùng với tính năng tải kiểu không đồng bộ, có thể cải thiện hành vi tải. Công cụ critters (trình tìm lỗi mã nguồn) tìm ra những kiểu được sử dụng trên trang bằng cách xem các bộ chọn trong một tệp kiểu và so khớp các bộ chọn đó với HTML. Khi tìm thấy một kiểu trùng khớp, trình phân tích sẽ xem xét các kiểu tương ứng như một phần của CSS quan trọng và đưa các kiểu đó vào cùng dòng.
Hãy xem ví dụ:
<head> <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'"> </head> <body> <section> <button class="primary"></button> </section> </body>
/* styles.css */ section button.primary { /* ... */ } .list { /* ... */ }
Trong ví dụ trên, trình kiểm tra sẽ đọc và phân tích cú pháp nội dung của styles.css
, sau đó so khớp hai bộ chọn với HTML và phát hiện ra rằng chúng ta sử dụng section button.primary
.
Cuối cùng, trình kiểm tra sẽ nội tuyến các kiểu tương ứng trong <head>
của trang, dẫn đến:
<head> <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'"> <style> section button.primary { /* ... */ } </style> </head> <body> <section> <button class="primary"></button> </section> </body>
Sau khi nội tuyến CSS quan trọng trong HTML, bạn sẽ thấy hiện tượng nhấp nháy của trang đã biến mất:
Tính năng nội tuyến CSS quan trọng hiện đã có trong Angular và được bật theo mặc định trong phiên bản 12. Nếu bạn đang sử dụng phiên bản 11, hãy bật tính năng này bằng cách đặt thuộc tính inlineCritical
thành true
trong angular.json
. Để chọn sử dụng tính năng này trong Next.js, hãy thêm experimental: { optimizeCss: true }
vào next.config.js
.
Kết luận
Trong bài đăng này, chúng ta đã đề cập đến một số hoạt động cộng tác giữa Chrome và các khung web. Nếu bạn là tác giả khung và nhận ra một số vấn đề mà chúng tôi đã giải quyết trong công nghệ của bạn, chúng tôi hy vọng những phát hiện của chúng tôi sẽ truyền cảm hứng để bạn áp dụng các biện pháp tối ưu hoá hiệu suất tương tự.
Tìm hiểu thêm về các điểm cải tiến. Bạn có thể xem danh sách toàn diện về các hoạt động tối ưu hoá mà chúng tôi đang thực hiện cho Core Web Vitals trong bài đăng Giới thiệu về Aurora.