Trong học phần trước, một số lý thuyết đằng sau đường dẫn hiển thị quan trọng là khám phá và cách các tài nguyên chặn hiển thị và chặn trình phân tích cú pháp có thể trì hoãn một sự kiện lần hiển thị ban đầu của trang. Giờ bạn đã hiểu một số lý thuyết Vậy là bạn đã sẵn sàng để tìm hiểu một số kỹ thuật để tối ưu hoá đường dẫn kết xuất.
Khi một trang tải, nhiều tài nguyên được tham chiếu trong HTML của trang đó cung cấp với giao diện và bố cục thông qua CSS, cũng như tính tương tác của trang thông qua JavaScript. Trong học phần này, một số khái niệm quan trọng liên quan đến chúng tôi sẽ đề cập đến các tài nguyên này và mức độ ảnh hưởng của chúng đối với thời gian tải của trang.
Chặn hiển thị
Như đã thảo luận trong mô-đun trước, CSS là một tài nguyên render-blocking, vì lệnh này chặn trình duyệt để không hiển thị bất kỳ nội dung nào cho đến Mô hình đối tượng CSS (CSSOM) đã được tạo. Trình duyệt chặn hiển thị để ngăn flash Nội dung không định kiểu (FOUC), đây là yếu tố không được mong muốn trên quan điểm trải nghiệm người dùng.
Trong video trước, có một FOUC ngắn để bạn có thể xem trang mà không cần bất kỳ kiểu nào. Sau đó, tất cả các kiểu sẽ được áp dụng sau khi CSS của trang đã đã tải xong từ mạng, và phiên bản chưa định kiểu của trang là ngay lập tức được thay thế bằng phiên bản được tạo kiểu.
Nói chung, FOUC là thứ bạn thường không thấy, nhưng đó là khái niệm là rất quan trọng để bạn biết lý do trình duyệt chặn hiển thị của trang cho đến khi CSS được tải xuống và áp dụng cho trang. Chặn hiển thị không hẳn là điều không như mong muốn nhưng bạn muốn giảm thiểu khoảng thời gian đảm bảo CSS của bạn được tối ưu hoá.
Chặn trình phân tích cú pháp
Tài nguyên chặn trình phân tích cú pháp sẽ làm gián đoạn trình phân tích cú pháp HTML, chẳng hạn như <script>
không có thuộc tính async
hoặc defer
. Khi trình phân tích cú pháp gặp
Phần tử <script>
, trình duyệt cần đánh giá và thực thi tập lệnh trước
tiếp tục phân tích cú pháp phần còn lại của HTML. Điều này là do thiết kế, vì tập lệnh có thể
sửa đổi hoặc truy cập DOM trong khi vẫn đang được xây dựng.
<!-- This is a parser-blocking script: -->
<script src="/script.js"></script>
Khi sử dụng các tệp JavaScript bên ngoài (không có async
hoặc defer
), trình phân tích cú pháp sẽ
cho đến khi tệp được tải xuống, phân tích cú pháp và
thực thi. Khi bạn sử dụng JavaScript cùng dòng, trình phân tích cú pháp cũng bị chặn theo cách tương tự cho đến
tập lệnh cùng dòng được phân tích cú pháp và thực thi.
Trình quét tải trước
Trình quét tải trước là một tính năng tối ưu hoá trình duyệt dưới dạng HTML phụ
trình phân tích cú pháp quét phản hồi HTML thô để tìm và tìm nạp theo suy đoán
trước khi trình phân tích cú pháp HTML chính phát hiện ra chúng. Cho
ví dụ: trình quét tải trước sẽ cho phép trình duyệt bắt đầu tải xuống tệp
tài nguyên được chỉ định trong phần tử <img>
, ngay cả khi trình phân tích cú pháp HTML bị chặn
trong khi tìm nạp và xử lý các tài nguyên như CSS và JavaScript.
Để tận dụng trình quét tải trước, bạn nên đưa các tài nguyên quan trọng vào trong mã đánh dấu HTML do máy chủ gửi. Các mẫu tải tài nguyên sau đây là không thể phát hiện bởi trình quét tải trước:
- Hình ảnh do CSS tải bằng cách sử dụng thuộc tính
background-image
. Những hình ảnh này tệp đối chiếu có trong CSS và không thể phát hiện được bằng trình quét tải trước. - Các tập lệnh được tải động dưới dạng mã đánh dấu phần tử
<script>
được chèn vào DOM bằng cách sử dụng JavaScript hoặc các mô-đun được tải bằngimport()
động. - HTML được hiển thị trên ứng dụng bằng JavaScript. Mã đánh dấu như vậy có trong các chuỗi trong tài nguyên JavaScript và không thể tìm thấy được khi tải trước .
- Khai báo CSS
@import
.
Các mẫu tải tài nguyên này đều là những tài nguyên được phát hiện muộn và do đó
không được hưởng lợi từ trình quét tải trước. Hãy tránh sử dụng các thành phần này bất cứ khi nào có thể. Nếu
không thể tránh được những mẫu đó, tuy nhiên, bạn có thể dùng
Gợi ý preload
để tránh chậm trễ trong việc khám phá tài nguyên.
CSS
CSS xác định cách trình bày và bố cục của trang. Như được mô tả trước đó, CSS là tài nguyên chặn hiển thị, vì vậy việc tối ưu hoá CSS có thể ảnh hưởng đáng kể đến tổng thời gian tải trang.
Thu nhỏ
Việc rút gọn tệp CSS giúp giảm kích thước tệp của tài nguyên CSS, nhờ đó tải xuống nhanh hơn. Điều này được thực hiện chủ yếu bằng cách xoá nội dung khỏi tệp CSS nguồn chẳng hạn như dấu cách và các ký tự vô hình khác, cũng như xuất kết quả cho một tệp mới được tối ưu hoá:
/* Unminified CSS: */
/* Heading 1 */
h1 {
font-size: 2em;
color: #000000;
}
/* Heading 2 */
h2 {
font-size: 1.5em;
color: #000000;
}
/* Minified CSS: */
h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}
Về hình thức cơ bản nhất, giảm thiểu CSS là một cách tối ưu hoá hiệu quả có thể cải thiện FCP của trang web và thậm chí là LCP trong một số trường hợp. Các công cụ như các gói có thể tự động thực hiện việc tối ưu hoá này cho bạn trong phiên bản chính thức bản dựng.
Xoá CSS không dùng
Trước khi hiển thị bất kỳ nội dung nào, trình duyệt cần tải xuống và phân tích cú pháp tất cả biểu định kiểu. Thời gian cần thiết để hoàn tất phân tích cú pháp cũng bao gồm các kiểu mà không được sử dụng trên trang hiện tại. Nếu bạn đang sử dụng trình gói kết hợp tất cả CSS vào một tệp duy nhất, thì người dùng có thể tải nhiều CSS xuống hơn cần thiết để hiển thị trang hiện tại.
Để tìm hiểu CSS không dùng cho trang hiện tại, hãy sử dụng công cụ Mức độ phù hợp trong Chrome Công cụ cho nhà phát triển.
Việc xoá CSS không sử dụng có tác động gấp đôi: ngoài việc giảm số lượt tải xuống bạn đang tối ưu hoá việc xây dựng cây kết xuất, vì trình duyệt cần xử lý ít quy tắc CSS hơn.
Tránh khai báo CSS @import
Mặc dù việc này có vẻ thuận tiện, nhưng bạn nên tránh khai báo @import
trong CSS:
/* Don't do this: */
@import url('style.css');
Tương tự như cách hoạt động của phần tử <link>
trong HTML, phần khai báo @import
trong CSS cho phép bạn nhập tài nguyên CSS bên ngoài từ trong biểu định kiểu. Chiến lược phát hành đĩa đơn
Sự khác biệt chính giữa hai phương pháp này là phần tử HTML <link>
là một phần của phản hồi HTML và do đó được phát hiện sớm hơn nhiều so với CSS
là tệp khai báo @import
tải xuống.
Lý do là để khai báo @import
mà bạn phát hiện thấy, tệp CSS chứa tệp đó phải được tải xuống trước tiên. Chiến dịch này
dẫn đến một chuỗi yêu cầu bị trì hoãn trong trường hợp CSS
thời gian cần thiết để một trang hiển thị lần đầu. Một nhược điểm khác là
không thể phát hiện các biểu định kiểu được tải bằng cách sử dụng khai báo @import
bằng
tải trước trình quét, từ đó trở thành tài nguyên chặn hiển thị được phát hiện muộn.
<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">
Trong hầu hết các trường hợp, bạn có thể thay thế @import
bằng cách sử dụng
Phần tử <link rel="stylesheet">
. Phần tử <link>
cho phép biểu định kiểu
được tải xuống đồng thời và giảm tổng thời gian tải, so với @import
để tải các tờ khai định kiểu xuống liên tục.
CSS quan trọng cùng dòng
Thời gian cần để tải các tệp CSS xuống có thể làm tăng FCP của trang. Cùng dòng
kiểu quan trọng trong tài liệu <head>
loại bỏ yêu cầu mạng cho
và khi được thực hiện đúng cách, tài nguyên CSS có thể cải thiện thời gian tải ban đầu khi
bộ nhớ đệm trên trình duyệt của người dùng chưa được chuẩn bị. CSS còn lại có thể tải được
không đồng bộ hoặc được thêm vào cuối phần tử <body>
.
<head>
<title>Page Title</title>
<!-- ... -->
<style>h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}</style>
</head>
<body>
<!-- Other page markup... -->
<link rel="stylesheet" href="non-critical.css">
</body>
Tuy nhiên, nhược điểm là việc đặt một lượng lớn CSS cùng dòng sẽ thêm nhiều byte hơn vào phần đầu Phản hồi HTML. Bởi vì tài nguyên HTML thường không thể được lưu vào bộ nhớ đệm trong thời gian quá dài—hoặc tại tất cả—điều này có nghĩa là CSS cùng dòng không được lưu vào bộ nhớ đệm cho các trang tiếp theo mà có thể sử dụng cùng một CSS trong các biểu định kiểu bên ngoài. Kiểm tra và đo lường hiệu suất để đảm bảo đánh đổi xứng đáng với công sức bỏ ra.
Bản minh hoạ CSS
JavaScript
JavaScript thúc đẩy hầu hết các hoạt động tương tác trên web nhưng phải trả phí. Việc vận chuyển quá nhiều JavaScript có thể làm cho trang web của bạn phản hồi chậm trong trang tải và thậm chí có thể gây ra sự cố về thời gian phản hồi làm chậm tương tác — cả hai có thể gây khó chịu cho người dùng.
JavaScript chặn hiển thị
Khi tải các phần tử <script>
mà không có thuộc tính defer
hoặc async
,
trình duyệt chặn phân tích cú pháp và hiển thị cho đến khi tập lệnh được tải xuống, phân tích cú pháp và
thực thi. Tương tự, tập lệnh cùng dòng chặn trình phân tích cú pháp cho đến khi tập lệnh được phân tích cú pháp
và thực thi.
async
đấu với defer
async
và defer
cho phép các tập lệnh bên ngoài tải mà không chặn HTML
trình phân tích cú pháp trong khi các tập lệnh (bao gồm cả tập lệnh cùng dòng) với type="module"
là
tự động được hoãn lại. Tuy nhiên, async
và defer
có một số điểm khác biệt
là điều quan trọng cần hiểu.
Những tập lệnh tải bằng async
được phân tích cú pháp và thực thi ngay sau khi được tải xuống.
trong khi những tập lệnh được tải bằng defer
sẽ được thực thi khi phân tích cú pháp tài liệu HTML được
hoàn tất—việc này xảy ra cùng lúc với sự kiện DOMContentLoaded
của trình duyệt.
Ngoài ra, tập lệnh async
có thể thực thi không đúng thứ tự, trong khi tập lệnh defer
được thực thi theo thứ tự mà chúng xuất hiện trong thẻ đánh dấu.
Hiển thị phía máy khách
Nói chung, bạn nên tránh sử dụng JavaScript để hiển thị bất kỳ nội dung quan trọng nào hoặc phần tử LCP của trang. Đây được gọi là hiển thị phía máy khách và là một kỹ thuật được sử dụng rộng rãi trong các ứng dụng trang đơn (SPA).
Đánh dấu được hiển thị bằng JavaScript đi qua trình quét tải trước dưới dạng tài nguyên có trong mã đánh dấu do ứng dụng hiển thị không thể phát hiện được. Chiến dịch này có thể trì hoãn việc tải các tài nguyên quan trọng xuống, chẳng hạn như hình ảnh LCP. Trình duyệt chỉ bắt đầu tải hình ảnh LCP xuống sau khi tập lệnh đã thực thi và thêm phần tử vào DOM. Đổi lại, tập lệnh chỉ có thể được thực thi sau khi được khám phá, tải xuống và phân tích cú pháp. Đây gọi là yêu cầu quan trọng mà bạn nên tránh.
Ngoài ra, việc kết xuất mã đánh dấu bằng JavaScript có nhiều khả năng tạo ra các nhiệm vụ dài so với mã đánh dấu được tải xuống từ máy chủ để phản hồi một thao tác điều hướng của bạn. Việc sử dụng rộng rãi tính năng hiển thị HTML phía máy khách có thể ảnh hưởng tiêu cực độ trễ tương tác. Điều này đặc biệt đúng trong những trường hợp mà DOM của một trang rất lớn, kích hoạt công việc kết xuất đáng kể khi JavaScript sửa đổi DOM.
Thu nhỏ
Tương tự như CSS, việc giảm bớt JavaScript sẽ giảm kích thước tệp của tài nguyên tập lệnh. Điều này có thể giúp tải xuống nhanh hơn, cho phép trình duyệt chuyển sang phân tích cú pháp và biên dịch JavaScript nhanh hơn.
Ngoài ra, việc giảm kích thước JavaScript còn tiến xa hơn một bước so với việc giảm kích thước các thành phần khác, chẳng hạn như CSS. Khi JavaScript được giảm thiểu, nó không chỉ bị xoá về những mục như dấu cách, thẻ và nhận xét nhưng ký hiệu trong nguồn JavaScript được rút ngắn. Quá trình này đôi khi được gọi là không sử dụng được. Người nhận thấy sự khác biệt, hãy lấy mã nguồn JavaScript sau:
// Unuglified JavaScript source code:
export function injectScript () {
const scriptElement = document.createElement('script');
scriptElement.src = '/js/scripts.js';
scriptElement.type = 'module';
document.body.appendChild(scriptElement);
}
Khi mã nguồn JavaScript trước đó không chính xác, kết quả có thể trông chẳng hạn như đoạn mã sau:
// Uglified JavaScript production code:
export function injectScript(){const t=document.createElement("script");t.src="/js/scripts.js",t.type="module",document.body.appendChild(t)}
Trong đoạn mã trước, bạn có thể thấy rằng biến mà con người có thể đọc được
scriptElement
trong nguồn được rút ngắn thành t
. Khi được áp dụng trên một phạm vi lớn
tập hợp tập lệnh, thì khoản tiết kiệm có thể khá đáng kể mà không ảnh hưởng đến
các tính năng mà JavaScript sản xuất của trang web cung cấp.
Nếu bạn đang sử dụng trình theo gói để xử lý mã nguồn của trang web, hãy chọn không hợp lệ thường được thực hiện tự động cho các bản dựng chính thức. Đơn vị quảng cáo — chẳng hạn như Terser, ví dụ: — cũng có thể định cấu hình cao, cho phép bạn tinh chỉnh mức độ linh hoạt của thuật toán đơn giản hoá để tiết kiệm tối đa. Tuy nhiên, các chế độ mặc định cho mọi công cụ loại bỏ thông thường là đủ để cảnh cáo sự cân bằng hợp lý giữa kích thước đầu ra và khả năng duy trì.
Bản minh hoạ JavaScript
Kiểm tra kiến thức của bạn
Cách tốt nhất để tải nhiều tệp CSS trong trình duyệt là gì?
<link>
.@import
của CSS.Trình quét tải trước của trình duyệt làm gì?
<link rel="preload">
trong
tài nguyên HTML.
Tại sao theo mặc định, trình duyệt tạm thời chặn quá trình phân tích cú pháp HTML khi tải các tài nguyên JavaScript xuống?
Tiếp theo: Hỗ trợ trình duyệt bằng các gợi ý về tài nguyên
Giờ đây, bạn đã nắm được cách tải tài nguyên trong phần tử <head>
ảnh hưởng đến tải trang ban đầu và các chỉ số khác nhau, đã đến lúc tiếp tục. Trong thời gian tới
mô-đun, gợi ý về tài nguyên được khám phá và cách chúng có thể đưa ra gợi ý có giá trị
trình duyệt để bắt đầu tải tài nguyên và mở các kết nối đến nhiều nguồn gốc
sớm hơn trình duyệt nếu không có chúng.