Hiển thị HTML và tính tương tác phía máy khách

Hiển thị HTML bằng JavaScript khác với hiển thị HTML do máy chủ gửi và 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ần tương tác.

Phân tích cú pháp và hiển thị HTML là hoạt động mà theo mặc định, trình duyệt sẽ hoạt động rất hiệu quả đối với những trang web sử dụng logic điều hướng tích hợp 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ố định". Các 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ể tìm các chế độ mặc định của trình duyệt cho phù hợp với nhu cầu của ứng dụng. Điều này chắc chắn xảy ra đối với các trang web sử dụng mẫu ứng dụng trang đơn (SPA), một mô hình tự động tạo phần lớn của HTML/DOM trên máy 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 và có thể có ả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 công việc liên quan quá mức.

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 do máy chủ gửi đến trình duyệt so với việc tạo HTML trên ứng dụng khách bằng JavaScript, cũng như lý do HTML có thể dẫn đến độ trễ tương tác cao vào 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ượt tải trang truyền thống liên quan đến 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 đường liên kết trong MPA, thì chuỗi sự kiện sau đây sẽ xảy ra:

  1. Trình duyệt gửi một yêu cầu điều hướng cho URL được cung cấp.
  2. Máy chủ phản hồi bằng HTML theo từng phần.

Bước cuối cùng trong những việc này là quan trọng. Đây cũng là một trong những cách 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à truyền 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.

Ảnh chụp màn hì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ụ của Chrome cho nhà phát triển. Khi HTML truyền vào, các phần của HTML được xử lý qua nhiều tác vụ ngắn hơn và kết xuất có mức độ gia tăng.
Phân tích cú pháp và hiển thị HTML do máy chủ cung cấp như được hiển thị trong bảng hiệu suất của Công cụ của Chrome cho nhà phát triển. Các tác vụ liên quan đến việc phân tích cú pháp và hiển thị HTML được chia thành nhiều phần.

Giống như hầu hết mọi việc xảy ra trong trình duyệt, phân tích cú pháp HTML xảy ra trong các tác vụ. Khi HTML được truyền trực tuyến từ máy chủ đến trình duyệt, trình duyệt sẽ tối ưu hoá quá trình phân tích cú pháp HTML đó bằng cách thực hiện từng chút một dưới dạng các bit của luồng đó đến theo từng phần. Hệ quả là trình duyệt sẽ định kỳ chuyển tới luồng chính sau khi xử lý từng phân đoạn, nhờ đó 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 hiển thị gia tăng cần thiết để hiển thị trang cho người dùng, cũng như xử lý các tương tác người dùng có thể xảy ra trong giai đoạn khởi động quan trọng của trang. Phương pháp này giúp cải thiện điểm Lượt tương tác với Nội dung hiển thị tiếp theo (INP) tốt hơn cho trang.

Bạn cần lưu ý điều gì? Khi bạn truyền trực tuyến HTML từ máy chủ, bạn sẽ được phân tích cú pháp và hiển thị HTML tăng dần, đồng thời tự động lợi nhuận cho chuỗi chính mà không mất phí. Bạn sẽ không làm được điều đó bằng tính năng hiển thị 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 đến 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 liên quan đến 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 HTML vào vùng nội dung chính của trang bằng HTML được tập hợp từ dữ liệu đã tìm nạp từ máy chủ. Các lần điều hướng tiếp theo (đôi khi được gọi là "điều hướng mềm" trong trường hợp này) được JavaScript xử lý hoàn toàn để điền vào trang bằng HTML mới.

Quá trình 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 GAA trong những trường hợp hạn chế hơn 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:

  1. Thuộc tính innerHTML cho phép bạn đặt nội dung trên 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.
  2. 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ỳ phân tích cú pháp HTML nào của trình duyệt.
  3. 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 HTML, giống như trong phương pháp số 1). Tuy nhiên, vì một số lý do, bạn không nên sử dụng document.write.
Ảnh chụp màn hình quá trình phân tích cú pháp của HTML được hiển thị qua JavaScript được trực quan hoá trong bảng điều khiển hiệu suất của Công cụ của Chrome cho nhà phát triển. Tác vụ này diễn ra trong một tác vụ dài và đơn lẻ, chặn luồng chính.
Phân tích cú pháp và hiển thị HTML thông qua JavaScript trên máy khách như được hiển thị trong bảng điều khiển hiệu suất của Công cụ của Chrome cho nhà phát triển. Các tác vụ liên quan đến việc phân tích cú pháp và kết xuất chuỗi không được chia nhỏ, dẫn đến một tác vụ dài chặn luồng chính.

Hậu quả của việc tạo HTML/DOM thông qua JavaScript phía máy khách có thể rất quan trọng:

  • Không giống như HTML được máy chủ truyền trực tuyến để phản hồi một yêu cầu điều hướng, các tác vụ JavaScript trên ứng dụng khách 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 khách.
  • Nếu HTML được tạo trên ứng dụng khách trong quá trình khởi động, thì các tài nguyên được tham chiếu trong đó sẽ không được trình duyệt tải trước phát hiện. Điều này chắc chắn sẽ gây ả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 (thay vào đó là vấn đề về độ trễ mạng trong việc tìm nạp các tài nguyên quan trọng), nhưng bạn không nên để LCP của trang web bị ảnh hưởng khi vượt qua quy trình tối ưu hoá hiệu suất cơ bản của trình duyệt.

Những việc bạn có thể làm về tác động của tính năng kết xuất phía máy khách đối với hiệu suất

Nếu trang web của bạn phụ thuộc nhiều vào quá trình hiển thị phía máy khách và bạn nhận thấy giá trị INP kém trong dữ liệu trường của mình, thì có thể bạn sẽ muốn biết liệu tính năng hiển thị phía máy khách có liên quan đến vấn đề nào hay không. Ví dụ: nếu trang web của bạn là một SPA, thì dữ liệu trường của bạn có thể cho biết các lượt tương tác chịu trách nhiệm về công việc hiển thị đáng kể.

Bất kể lý do là gì, sau đây là một số nguyên nhân tiềm ẩn mà bạn có thể tìm hiểu để giúp mọi việc trở lại đúng hướng.

Cung cấp nhiều HTML từ máy chủ nhất có thể

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ỏ quá trình phân tích cú pháp và hiển thị HTML theo cách tránh được các tác vụ dài và 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ể 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 sẽ 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ẽ hạn chế số lần hiển thị phía máy khách ban đầu mà trang web của bạn sẽ cần đến, đồng thời mang lại trải nghiệm tốt hơn.

  • Đối với React, bạn cần sử dụng Server DOM API để hiển thị HTML trên máy chủ. Tuy nhiên, hãy lưu ý: phương pháp hiển thị phía máy chủ truyền thống sử dụng phương thức đồng bộ, điều này có thể làm Thời gian cho 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 trong thời gian sớm nhất có thể. Next.js (một khung dựa trên React) 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ủ, phần mềm này 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ư việc xác thực).
  • Theo mặc định, Vue cũng thực hiện 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 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 sử dụng bản tóm tắt cấp cao hơn cho dự án Vue để giúp bạn dễ dàng triển khai các phương pháp hay nhất.
  • Svelte kết xuất HTML trên máy chủ theo mặc định, mặc dù 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), thì bạn không thể hiển thị HTML của thành phần đó trên máy chủ. Hãy 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 quá trình kết xuất phía máy khách một cách không cần thiết. SvelteKit (đối với Svelte là Next.js) sẽ nhúng nhiều phương pháp hay nhất vào dự án Svelte của bạn nhất có thể, nhờ đó bạn có thể tránh các cạm bẫy tiềm ẩn trong các 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 DOM lớn, quá trình 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 một DOM hiện tại do hoạt động tương tác với MPA, hãy cân nhắc việc giữ cho các DOM đó càng nhỏ càng tốt. Điều này sẽ giúp giảm 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 đó, hy vọng sẽ giúp giảm INP của trang web.

Cân nhắc sử dụng kiến trúc trình chạy 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 cho mọi trường hợp sử dụng — nhưng là một kỹ thuật có thể biến MPA của bạn thành một trang web tạo cảm giác như trang web đang tải ngay lập tức khi người dùng điều hướng từ trang này sang trang khác. 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 trong khi sử dụng API ReadableStream để tìm nạp phần còn lại của HTML của một trang từ máy chủ.

Khi sử dụng thành công kỹ thuật này, bạn 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 ấn tượng rằng trang web của bạn đang tải rất nhanh. Các trang web sử dụng phương pháp này sẽ có cảm giác 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. Điều này cũng giảm số lượng HTML mà bạn đang yêu cầu từ máy chủ.

Tóm lại, kiến 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 của trình duyệt mà thêm vào logic đó. Để biết thêm thông tin về cách đạt được điều này bằng Workbox, hãy đọc bài viết Ứ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 để máy chủ gửi tất cả (hoặc hàng loạt) HTML cần thiết để trang web của mình hoạt động, bạn sẽ nhận được rất nhiều miễn phí: phân tích cú pháp và hiển thị tăng dần cũng như tự động tạo ra chuỗi chính để tránh các tác vụ kéo 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ẻ, không phải lúc nào bạn cũng có thể tránh được tình trạng này. Để giảm thiểu các công việc có thể tốn nhiều thời gian mà có thể dẫn đến quá nhiều lần hiển thị trang web khách hàng, hãy đảm bảo bạn gửi nhiều HTML của trang web từ máy chủ bất cứ khi nào có thể, giữ kích thước DOM 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 cấu trúc thay thế để tăng tốc độ phân phối HTML đến máy khách, đồng thời tận dụng việc phân tích cú pháp gia tăng và hiển thị 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 việc hiển thị phía máy khách của trang web, bạn sẽ 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 từ Unsplash, của Maik Jonietz.