Việc hiển thị HTML bằng JavaScript khác với việc hiển thị HTML do máy chủ gửi – và điều này có thể ảnh hưởng đến hiệu suất. Tìm hiểu sự khác biệt trong hướng dẫn này và những việc bạn có thể làm để duy trì hiệu suất hiển thị của trang web – đặc biệt là khi có quan tâm đến hoạt động tương tác.
Phân tích cú pháp và hiển thị HTML là tính năng mà theo mặc định, các trình duyệt hoạt động rất tốt đối với các trang web sử dụng logic điều hướng tích hợp sẵn của trình duyệt, đôi khi được gọi là "tải trang truyền thống" hoặc "điều hướng cứng". Những trang web như vậy đôi khi được gọi là ứng dụng nhiều trang (MPA).
Tuy nhiên, nhà phát triển có thể xử lý các ứng dụng mặc định của trình duyệt để phù hợp với nhu cầu ứng dụng của họ. Điều này chắc chắn đúng với các trang web sử dụng mẫu ứng dụng trang đơn (SPA). Mẫu này tự động tạo phần lớn HTML/DOM trên ứng dụng khách bằng JavaScript. Tính năng hiển thị phía máy khách là tên của mẫu thiết kế này. Hoạt động này có thể ảnh hưởng đến Lượt tương tác với nội dung hiển thị tiếp theo (INP) của trang web nếu lượng công việc liên quan quá nhiều.
Hướng dẫn này sẽ giúp bạn cân nhắc sự khác biệt giữa việc sử dụng HTML được máy chủ gửi đến trình duyệt so với việc tạo HTML trên máy khách bằng JavaScript, cũng như cách HTML này có thể dẫn đến độ trễ tương tác cao tại những thời điểm quan trọng.
Cách trình duyệt hiển thị HTML do máy chủ cung cấp
Mẫu điều hướng được sử dụng trong các lần tải trang truyền thống bao gồm việc nhận HTML từ máy chủ trong mỗi lần điều hướng. Nếu bạn nhập URL vào thanh địa chỉ của trình duyệt hoặc nhấp vào một liên kết trong MPA, chuỗi các sự kiện sau đây sẽ xảy ra:
- Trình duyệt sẽ gửi một yêu cầu điều hướng đến URL được cung cấp.
- Máy chủ phản hồi bằng HTML theo từng phần.
Bước cuối cùng là bước quan trọng. Đây cũng là một trong những giải pháp tối ưu hoá hiệu suất cơ bản nhất trong trao đổi máy chủ/trình duyệt và được gọi là phát trực tuyến. Nếu máy chủ có thể bắt đầu gửi HTML sớm nhất có thể và trình duyệt không đợi toàn bộ phản hồi đến thì trình duyệt có thể xử lý HTML theo từng phần khi nó đến.
![Ảnh chụp màn hình về quá trình phân tích cú pháp HTML do máy chủ gửi được hiển thị trong bảng điều khiển hiệu suất của Công cụ cho nhà phát triển của Chrome. Khi luồng HTML ở trong, các phần của luồng này được xử lý trong nhiều tác vụ ngắn hơn và việc hiển thị được gia tăng.](https://web.developers.google.cn/static/articles/client-side-rendering-of-html-and-interactivity/image/a-screenshot-parsing-ht-f2443fe1b1888.png?authuser=5&hl=vi)
Giống như hầu hết những thứ xảy ra trong trình duyệt, quá trình phân tích cú pháp HTML diễn ra trong các tác vụ. Khi HTML được truyền từ máy chủ đến trình duyệt, trình duyệt sẽ tối ưu hoá việc phân tích cú pháp HTML đó bằng cách thực hiện mỗi lần một chút khi các bit của luồng đó xuất hiện trong các đoạn. Hậu quả là trình duyệt sẽ chuyển sang luồng chính theo định kỳ sau khi xử lý từng đoạn, do đó tránh được các tác vụ dài. Điều này có nghĩa là công việc khác có thể xảy ra trong khi HTML được phân tích cú pháp, bao gồm công việc kết xuất gia tăng cần thiết để hiển thị trang cho người dùng, cũng như xử lý tương tác của người dùng có thể xảy ra trong giai đoạn khởi động quan trọng của trang. Cách tiếp cận này giúp cải thiện điểm số Lượt tương tác với nội dung hiển thị tiếp theo (INP) cho trang.
Bạn cần lưu ý điều gì? Khi phát trực tuyến HTML từ máy chủ, bạn sẽ được phân tích cú pháp và hiển thị dần dần HTML, đồng thời tự động được cung cấp miễn phí cho luồng chính. Bạn không hiểu được điều đó khi kết xuất phía máy khách.
Cách trình duyệt hiển thị HTML do JavaScript cung cấp
Mặc dù mọi yêu cầu điều hướng tới một trang đều yêu cầu máy chủ cung cấp một lượng HTML nhất định, nhưng một số trang web sẽ sử dụng mẫu SPA. Phương pháp này thường bao gồm tải trọng ban đầu tối thiểu của HTML do máy chủ cung cấp, nhưng sau đó máy khách sẽ điền sẵn vào vùng nội dung chính của trang bằng HTML được tập hợp từ dữ liệu được tìm nạp từ máy chủ. Các lần điều hướng tiếp theo, đôi khi còn được gọi là "thao tác mềm" trong trường hợp này – được JavaScript xử lý hoàn toàn để điền HTML mới vào trang.
Hiển thị phía máy khách cũng có thể xảy ra trong các trường hợp không phải làSPA trong một số ít trường hợp khi HTML được tự động thêm vào DOM thông qua JavaScript.
Có một số cách phổ biến để tạo HTML hoặc thêm vào DOM thông qua JavaScript:
- Thuộc tính
innerHTML
cho phép bạn đặt nội dung trên một phần tử hiện có thông qua một chuỗi mà trình duyệt phân tích cú pháp thành DOM. - Phương thức
document.createElement
cho phép bạn tạo các phần tử mới để thêm vào DOM mà không cần sử dụng bất kỳ quá trình phân tích cú pháp HTML nào của trình duyệt. - Phương thức
document.write
cho phép bạn ghi HTML vào tài liệu (và trình duyệt phân tích cú pháp tài liệu này, giống như trong phương pháp số 1). Tuy nhiên, vì một số lý do, bạn tuyệt đối không nên sử dụngdocument.write
.
![Ảnh chụp màn hình về quá trình phân tích cú pháp HTML kết xuất qua JavaScript, được trình bày trực quan trong bảng điều khiển hiệu suất của Công cụ cho nhà phát triển của Chrome. Công việc diễn ra trong một tác vụ đơn lẻ, dài hạn chặn luồng chính.](https://web.developers.google.cn/static/articles/client-side-rendering-of-html-and-interactivity/image/a-screenshot-parsing-ht-7b89c1ab03511.png?authuser=5&hl=vi)
Hậu quả của việc tạo HTML/DOM thông qua JavaScript phía máy khách có thể là đáng kể:
- Không giống như HTML được máy chủ truyền trực tuyến để phản hồi yêu cầu điều hướng, các tác vụ JavaScript trên ứng dụng không tự động được chia nhỏ. Điều này có thể dẫn đến các tác vụ dài chặn luồng chính. Điều này có nghĩa là INP của trang có thể bị ảnh hưởng tiêu cực nếu bạn đang tạo quá nhiều HTML/DOM cùng một lúc trên ứng dụng.
- Nếu HTML được tạo trên ứng dụng trong quá trình khởi động, thì trình quét tải trước của trình duyệt sẽ không phát hiện thấy các tài nguyên được tham chiếu trong đó. Điều này chắc chắn sẽ có ảnh hưởng tiêu cực đến Thời gian hiển thị nội dung lớn nhất (LCP) của trang. Mặc dù đây không phải là vấn đề về hiệu suất trong thời gian chạy (mà là do mạng chậm trễ trong việc tìm nạp các tài nguyên quan trọng), nhưng bạn không muốn LCP của trang web bị ảnh hưởng khi bỏ qua bước tối ưu hoá hiệu suất cơ bản này của trình duyệt.
Những việc bạn có thể làm để giảm tác động của việc hiển thị phía máy khách đến hiệu suất
Nếu trang web của bạn phụ thuộc nhiều vào tính năng hiển thị phía máy khách và bạn thấy giá trị INP thấp trong dữ liệu trường của mình, thì bạn có thể tự hỏi liệu hiển thị phía máy khách có liên quan gì đến vấn đề không. Ví dụ: nếu trang web của bạn là một SPA, thì dữ liệu trong trường của bạn có thể cho thấy các lượt tương tác ảnh hưởng đến việc hiển thị đáng kể.
Dù lý do là gì thì bạn có thể tìm hiểu một số nguyên nhân tiềm ẩn sau đây để giúp mọi việc đi đúng hướng.
Cung cấp càng nhiều HTML từ máy chủ càng tốt
Như đã đề cập trước đó, theo mặc định, trình duyệt xử lý HTML từ máy chủ theo cách rất hiệu quả. Tính năng này sẽ chia nhỏ hoạt động phân tích cú pháp và hiển thị HTML theo cách giúp tránh các thao tác dài, đồng thời tối ưu hoá tổng thời gian của luồng chính. Điều này dẫn đến Tổng thời gian chặn (TBT) thấp hơn và TBT tương quan chặt chẽ với INP.
Bạn có thể đang dựa vào khung giao diện người dùng để xây dựng trang web của mình. Nếu có, bạn cần đảm bảo rằng bạn đang hiển thị HTML thành phần trên máy chủ. Điều này sẽ giới hạn số lần hiển thị phía máy khách ban đầu mà trang web của bạn cần phải có và sẽ mang lại trải nghiệm tốt hơn.
- Đối với React, bạn sẽ cần sử dụng Server DOM API (API DOM máy chủ) để hiển thị HTML trên máy chủ. Tuy nhiên, hãy lưu ý: phương pháp truyền thống của tính năng hiển thị phía máy chủ sử dụng phương pháp đồng bộ, nên có thể dẫn đến Thời gian xuất hiện byte đầu tiên (TTFB) dài hơn, cũng như các chỉ số tiếp theo như Thời gian hiển thị nội dung đầu tiên (FCP) và LCP. Nếu có thể, hãy đảm bảo bạn đang sử dụng API truyền trực tuyến cho Node.js hoặc các môi trường thời gian chạy JavaScript khác để máy chủ có thể bắt đầu truyền trực tuyến HTML đến trình duyệt càng sớm càng tốt. Next.js (một khung dựa trên Phản ứng) cung cấp nhiều phương pháp hay nhất theo mặc định. Ngoài việc tự động hiển thị HTML trên máy chủ, Trình quản lý thẻ của Google cũng có thể tạo HTML tĩnh cho các trang không thay đổi dựa trên ngữ cảnh của người dùng (chẳng hạn như xác thực).
- Theo mặc định, Vue cũng thực hiện việc kết xuất phía máy khách. Tuy nhiên, giống như React, Vue cũng có thể kết xuất HTML thành phần của bạn trên máy chủ. Hãy tận dụng các API phía máy chủ này nếu có thể hoặc cân nhắc bản tóm tắt cấp cao hơn cho dự án Vue của bạn để triển khai các phương pháp hay nhất một cách dễ dàng hơn.
- Svelte hiển thị HTML trên máy chủ theo mặc định. Tuy nhiên, nếu mã thành phần của bạn cần quyền truy cập vào không gian tên dành riêng cho trình duyệt (ví dụ:
window
), bạn có thể không kết xuất được HTML của thành phần đó trên máy chủ. Khám phá các phương pháp thay thế bất cứ khi nào có thể để bạn không gây ra tình trạng kết xuất phía máy khách một cách không cần thiết. SvelteKit – tức là Svelte gọi là Next.js – nhúng nhiều phương pháp hay nhất vào dự án Svelte của bạn nhất có thể để bạn có thể tránh được những cạm bẫy tiềm ẩn trong những dự án chỉ sử dụng Svelte.
Giới hạn số lượng nút DOM được tạo trên ứng dụng
Khi các DOM lớn, việc xử lý cần thiết để hiển thị chúng có xu hướng tăng lên. Cho dù trang web của bạn là một SPA chính thức hay đang chèn các nút mới vào DOM hiện tại do kết quả của một sự tương tác của một MPA, hãy cân nhắc việc giữ các DOM đó càng nhỏ càng tốt. Điều này sẽ giúp giảm khối lượng công việc cần thiết trong quá trình hiển thị phía máy khách để hiển thị HTML đó, với hy vọng sẽ giúp giảm INP của trang web của bạn.
Cân nhắc cấu trúc của trình thực thi dịch vụ truyền trực tuyến
Đây là một kỹ thuật nâng cao — một kỹ thuật có thể không hoạt động dễ dàng trong mọi trường hợp sử dụng — nhưng đó là kỹ thuật có thể biến MPA của bạn thành một trang web cho cảm giác như trang web tải ngay lập tức khi người dùng điều hướng từ trang này đến trang tiếp theo. Bạn có thể sử dụng trình chạy dịch vụ để lưu trước các phần tĩnh của trang web trong CacheStorage
vào bộ nhớ đệm trong khi sử dụng API ReadableStream
để tìm nạp phần HTML còn lại của trang từ máy chủ.
Khi sử dụng thành công kỹ thuật này, bạn đang không tạo HTML trên máy khách, nhưng việc tải ngay một phần nội dung từ bộ nhớ đệm sẽ tạo cảm giác rằng trang web của bạn đang tải nhanh. Các trang web sử dụng phương pháp này có thể trông gần giống như một SPA, nhưng không có sự cố khi hiển thị phía máy khách. Việc này cũng giảm số lượng HTML mà bạn yêu cầu từ máy chủ.
Tóm lại, cấu trúc trình chạy dịch vụ truyền trực tuyến không thay thế logic điều hướng tích hợp sẵn của trình duyệt mà thêm vào đó. Để biết thêm thông tin về cách đạt được điều này với Workbox, hãy đọc Ứng dụng nhiều trang nhanh hơn có luồng.
Kết luận
Cách trang web của bạn nhận và hiển thị HTML có tác động đến hiệu suất. Khi bạn dựa vào máy chủ để gửi tất cả (hoặc phần lớn) HTML cần thiết để trang web của bạn hoạt động, bạn sẽ nhận được rất nhiều lợi ích miễn phí: phân tích cú pháp và hiển thị gia tăng, đồng thời tự động chuyển sang chuỗi chính để tránh các tác vụ dài.
Hiển thị HTML phía máy khách gây ra một số vấn đề tiềm ẩn về hiệu suất có thể tránh được trong nhiều trường hợp. Tuy nhiên, do các yêu cầu của từng trang web riêng lẻ, điều này không phải lúc nào cũng có thể tránh được. Để giảm thiểu các tác vụ dài tiềm ẩn có thể xảy ra do hiển thị quá nhiều trên trang web của máy khách, hãy đảm bảo rằng bạn đang gửi nhiều HTML của trang web từ máy chủ bất cứ khi nào có thể, giữ cho kích thước DOM của bạn nhỏ nhất có thể cho HTML phải được hiển thị trên máy khách và xem xét các kiến trúc thay thế để tăng tốc độ phân phối HTML tới máy khách đồng thời tận dụng việc phân tích cú pháp và hiển thị gia tăng trình duyệt cung cấp cho HTML được tải từ máy chủ.
Nếu có thể giảm tối đa khả năng hiển thị phía máy khách của trang web, thì bạn không chỉ cải thiện INP của trang web mà còn cải thiện các chỉ số khác như LCP, TBT và thậm chí cả TTFB của bạn trong một số trường hợp.
Hình ảnh chính trên trang Unsplash của Maik Jonietz.