Kích thước DOM lớn ảnh hưởng đến khả năng tương tác và việc bạn có thể làm

Kích thước DOM lớn có nhiều ảnh hưởng đến khả năng tương tác hơn bạn nghĩ. Hướng dẫn này giải thích lý do và những việc bạn có thể làm.

Không có cách nào để xử lý vấn đề này: khi bạn xây dựng một trang web, trang đó sẽ có Mô hình đối tượng tài liệu (DOM). DOM thể hiện cấu trúc HTML của trang, cho phép JavaScript và CSS truy cập vào cấu trúc và nội dung của trang.

Tuy nhiên, vấn đề là kích thước của DOM ảnh hưởng đến khả năng hiển thị trang nhanh chóng và hiệu quả của trình duyệt. Nói chung, DOM càng lớn thì chi phí ban đầu để hiển thị trang đó rồi cập nhật lại sau trong vòng đời của trang càng đắt đỏ.

Điều này trở nên khó khăn ở các trang có DOM rất lớn khi các tương tác sửa đổi hoặc cập nhật bố cục tiêu tốn nhiều tài nguyên kích hoạt DOM ảnh hưởng đến khả năng phản hồi nhanh của trang. Công việc bố cục tốn kém 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 một trang. Nếu bạn muốn một trang phản hồi nhanh chóng với các lượt tương tác của người dùng, bạn cần đảm bảo kích thước DOM của mình chỉ lớn khi cần thiết.

Khi nào DOM của một trang quá lớn?

Theo Lighthouse, kích thước DOM của một trang quá thừa khi vượt quá 1.400 nút. Lighthouse sẽ bắt đầu gửi cảnh báo khi DOM của trang vượt quá 800 nút. Hãy lấy HTML sau làm ví dụ:

<ul>
  <li>List item one.</li>
  <li>List item two.</li>
  <li>List item three.</li>
</ul>

Trong mã trên, có 4 phần tử DOM: phần tử <ul> và 3 phần tử con <li>. Trang web của bạn gần như chắc chắn sẽ có nhiều nút hơn số này, vì vậy điều quan trọng là phải hiểu bạn có thể làm gì để kiểm soát kích thước DOM, cũng như các chiến lược khác để tối ưu hóa công việc hiển thị khi bạn đã có DOM của trang nhỏ nhất có thể.

DOM lớn ảnh hưởng như thế nào đến hiệu suất trang?

DOM lớn ảnh hưởng đến hiệu suất của trang theo một số cách:

  1. Trong lần hiển thị đầu tiên của trang. Khi áp dụng CSS cho một trang, một cấu trúc tương tự như DOM có tên là Mô hình đối tượng CSS (CSSOM) sẽ được tạo. Khi bộ chọn CSS tăng mức độ cụ thể, CSSOM trở nên phức tạp hơn và cần nhiều thời gian hơn để chạy công việc cần thiết để chạy bố cục, định kiểu, kết hợp và tô màu cần thiết nhằm vẽ trang web lên màn hình. Việc bổ sung này làm tăng độ trễ tương tác cho những lượt tương tác xảy ra sớm trong quá trình tải trang.
  2. Khi các lượt tương tác sửa đổi DOM, thông qua việc chèn hoặc xoá phần tử hoặc bằng cách sửa đổi nội dung và kiểu của DOM, công việc cần thiết để hiển thị bản cập nhật đó có thể dẫn đến công việc bố cục, tạo kiểu, kết hợp và tô rất tốn kém. Tương tự như trường hợp hiển thị ban đầu của trang, sự gia tăng về tính đặc trưng của bộ chọn CSS có thể làm tăng công việc hiển thị khi các phần tử HTML được chèn vào DOM là kết quả của một hoạt động tương tác.
  3. Khi JavaScript truy vấn DOM, các tham chiếu đến các phần tử DOM được lưu trữ trong bộ nhớ. Ví dụ: nếu bạn gọi document.querySelectorAll để chọn tất cả các phần tử <div> trên một trang, chi phí bộ nhớ có thể đáng kể nếu kết quả trả về một số lượng lớn các phần tử DOM.
Ảnh chụp màn hình một nhiệm vụ dài do công việc kết xuất hình ảnh quá mức gây ra trong bảng hiệu suất của Công cụ của Chrome cho nhà phát triển. Ngăn xếp lệnh gọi của nhiệm vụ dài cho thấy thời gian đáng kể dành cho việc tính toán lại kiểu trang, cũng như vẽ trước.
Một tác vụ dài như hiển thị trong trình phân tích hiệu suất trong Công cụ của Chrome cho nhà phát triển. Tác vụ mất nhiều thời gian hiển thị là do chèn các phần tử DOM vào một DOM lớn thông qua JavaScript.

Tất cả các yếu tố này đều có thể ảnh hưởng đến khả năng tương tác, nhưng mục thứ hai trong danh sách trên có tầm quan trọng đặc biệt. Nếu một lượt tương tác dẫn đến thay đổi đối với DOM, thì lượt tương tác đó có thể khởi động nhiều hoạt động góp phần gây ra INP thấp trên trang.

Làm cách nào để đo lường kích thước DOM?

Bạn có thể đo lường kích thước DOM theo một số cách. Phương thức đầu tiên sử dụng Lighthouse. Khi bạn chạy một quy trình kiểm tra, số liệu thống kê về DOM của trang hiện tại sẽ nằm trong phần kiểm tra "Tránh kích thước DOM quá lớn" thuộc tiêu đề "Chẩn đoán". Trong phần này, bạn có thể thấy tổng số phần tử DOM, phần tử DOM chứa nhiều phần tử con nhất, cũng như phần tử DOM sâu nhất.

Một phương pháp đơn giản hơn bao gồm sử dụng bảng điều khiển JavaScript trong công cụ cho nhà phát triển trong bất kỳ trình duyệt chính nào. Để biết tổng số phần tử HTML trong DOM, bạn có thể sử dụng mã sau trong bảng điều khiển sau khi trang tải xong:

document.querySelectorAll('*').length;

Nếu muốn xem thông tin cập nhật về kích thước DOM theo thời gian thực, bạn cũng có thể sử dụng công cụ giám sát hiệu suất. Sử dụng công cụ này, bạn có thể liên hệ các hoạt động bố cục và định kiểu (và các khía cạnh hiệu suất khác) cùng với kích thước DOM hiện tại.

Ảnh chụp màn hình của trình theo dõi hiệu suất trong Công cụ của Chrome cho nhà phát triển. Ở bên trái, bạn có thể theo dõi liên tục nhiều khía cạnh khác nhau về hiệu suất của trang trong suốt thời gian hoạt động của trang. Trong ảnh chụp màn hình, số nút DOM, bố cục mỗi giây và tính toán lại kiểu trên mỗi phần đang được tích cực giám sát.
Trình giám sát hiệu suất trong Công cụ của Chrome cho nhà phát triển. Trong chế độ xem này, số nút DOM hiện tại của trang được lập biểu đồ cùng với hoạt động bố cục và tính toán lại kiểu được thực hiện mỗi giây.

Nếu kích thước của DOM đạt đến ngưỡng cảnh báo của kích thước Lighthouse DOM hoặc hoàn toàn thất bại, thì bước tiếp theo là tìm hiểu cách giảm kích thước của DOM nhằm cải thiện khả năng phản hồi các tương tác của người dùng nhằm cải thiện INP của trang web.

Làm cách nào để đo lường số lượng phần tử DOM bị ảnh hưởng bởi một lượt tương tác?

Nếu đang lập hồ sơ một hoạt động tương tác chậm trong phòng thí nghiệm mà bạn nghi ngờ có thể liên quan đến kích thước DOM của trang, bạn có thể tìm ra số lượng phần tử DOM bị ảnh hưởng bằng cách chọn bất kỳ hoạt động nào trong trình phân tích tài nguyên có nhãn "Tính toán lại kiểu" và quan sát dữ liệu theo ngữ cảnh trong bảng dưới cùng.

Ảnh chụp màn hình về hoạt động tính toán lại kiểu đã chọn trong bảng hiệu suất của Công cụ của Chrome cho nhà phát triển. Ở trên cùng, kênh tương tác cho thấy một lượt tương tác nhấp và phần lớn công việc được dùng để tính toán lại kiểu và vẽ trước. Ở dưới cùng, một bảng điều khiển cho thấy thêm thông tin chi tiết về hoạt động đã chọn, báo cáo rằng 2.547 phần tử DOM đã bị ảnh hưởng.
Quan sát số lượng phần tử bị ảnh hưởng trong DOM do việc tính toán lại kiểu. Lưu ý rằng phần được tô bóng của lượt tương tác trong kênh tương tác thể hiện phần thời lượng tương tác kéo dài hơn 200 mili giây, là ngưỡng "tốt" được chỉ định cho INP.

Trong ảnh chụp màn hình ở trên, hãy quan sát thấy việc tính toán lại kiểu của công việc (khi được chọn) cho biết số lượng phần tử bị ảnh hưởng. Mặc dù ảnh chụp màn hình ở trên cho thấy một trường hợp nghiêm trọng về tác động của kích thước DOM đến việc hiển thị hoạt động trên trang có nhiều phần tử DOM, nhưng thông tin chẩn đoán này vẫn hữu ích trong mọi trường hợp để xác định xem kích thước của DOM có phải là yếu tố hạn chế trong thời gian cần để khung tiếp theo hiển thị để phản hồi một tương tác hay không.

Làm cách nào để giảm kích thước DOM?

Ngoài việc kiểm tra HTML của trang web để xác định mã đánh dấu không cần thiết, cách chính để giảm kích thước DOM là giảm độ sâu của DOM. Một tín hiệu cho thấy DOM có thể sâu một cách không cần thiết là nếu bạn thấy mã đánh dấu có dạng như sau trong thẻ Phần tử của công cụ cho nhà phát triển trên trình duyệt:

<div>
  <div>
    <div>
      <div>
        <!-- Contents -->
      </div>
    </div>
  </div>
</div>

Khi thấy các mẫu như thế này, bạn có thể đơn giản hoá chúng bằng cách làm phẳng cấu trúc DOM. Làm như vậy sẽ làm giảm số lượng phần tử DOM và có thể mang lại cho bạn cơ hội để đơn giản hóa kiểu trang.

Chiều sâu DOM cũng có thể là dấu hiệu của khung mà bạn sử dụng. Cụ thể, các khung dựa trên thành phần (chẳng hạn như các khung dựa trên JSX) đòi hỏi bạn phải lồng nhiều thành phần trong một vùng chứa mẹ.

Tuy nhiên, nhiều khung cho phép bạn tránh lồng các thành phần bằng cách sử dụng cái gọi là mảnh. Khung dựa trên thành phần cung cấp mảnh dưới dạng một tính năng bao gồm (nhưng không giới hạn ở) những tính năng sau:

Bằng cách sử dụng các mảnh theo khung lựa chọn của bạn, bạn có thể giảm độ sâu của DOM. Nếu lo ngại về tác động của việc làm phẳng cấu trúc DOM đối với việc tạo kiểu, bạn có thể hưởng lợi từ việc sử dụng chế độ bố cục hiện đại hơn (và nhanh hơn) như flexbox hoặc grid.

Các chiến lược khác cần cân nhắc

Ngay cả khi bạn tốn nhiều công sức để làm phẳng cây DOM và xoá các phần tử HTML không cần thiết để giữ cho DOM nhỏ nhất có thể, nó vẫn có thể khá lớn và bắt đầu nhiều công việc hiển thị khi nó thay đổi theo tương tác của người dùng. Nếu thấy mình đang ở vị trí này, thì bạn có thể cân nhắc một số chiến lược khác để hạn chế công việc kết xuất.

Cân nhắc một phương pháp bổ sung

Trong lần đầu hiển thị, phần lớn trang của bạn có thể đang ở vị trí mà người dùng không thể nhìn thấy phần lớn trang. Đây có thể là cơ hội để tải từng phần HTML bằng cách bỏ qua các phần đó của DOM khi khởi động, nhưng thêm chúng vào khi người dùng tương tác với các phần của trang yêu cầu các khía cạnh ẩn ban đầu của trang.

Phương pháp này hữu ích cả trong quá trình tải ban đầu và thậm chí sau này. Đối với tải trang ban đầu, bạn sẽ mất ít công việc kết xuất hơn trước, nghĩa là tải trọng HTML ban đầu của bạn sẽ nhẹ hơn và hiển thị nhanh hơn. Nhờ đó, các hoạt động tương tác trong giai đoạn quan trọng đó sẽ có thêm cơ hội hoạt động mà không phải cạnh tranh để có được sự chú ý của luồng chính.

Nếu nhiều phần của trang ban đầu bị ẩn khi tải, điều này cũng có thể đẩy nhanh các hoạt động tương tác khác kích hoạt công việc hiển thị lại. Tuy nhiên, khi các lượt tương tác khác bổ sung thêm vào DOM, công việc hiển thị sẽ tăng lên khi DOM phát triển trong suốt vòng đời của trang.

Việc thêm vào DOM theo thời gian có thể khó khăn và nó cũng có sự đánh đổi riêng. Nếu đi theo cách này, có khả năng bạn đang thực hiện các yêu cầu mạng để lấy dữ liệu nhằm điền HTML mà bạn định thêm vào trang để phản hồi tương tác của người dùng. Mặc dù các yêu cầu mạng đang tiến hành không được tính vào INP, nhưng nó có thể làm tăng độ trễ dự kiến. Nếu có thể, hãy hiển thị vòng quay đang tải hoặc chỉ báo khác cho biết dữ liệu đang được tìm nạp để người dùng hiểu là có gì đó đang xảy ra.

Giới hạn độ phức tạp của bộ chọn CSS

Khi phân tích cú pháp các bộ chọn trong CSS của bạn, trình duyệt phải truyền qua cây DOM để hiểu cách thức và liệu các bộ chọn đó áp dụng cho bố cục hiện tại như thế nào. Các bộ chọn này càng phức tạp, thì trình duyệt càng phải làm nhiều việc để thực hiện cả quá trình hiển thị ban đầu của trang, cũng như tăng việc tính toán lại kiểu và bố cục nếu trang thay đổi là kết quả của một tương tác.

Dùng thuộc tính content-visibility

CSS cung cấp thuộc tính content-visibility. Đây là một cách hiệu quả để hiển thị từng phần các phần tử DOM ngoài màn hình. Khi các thành phần tiến đến khung nhìn, chúng sẽ được hiển thị theo yêu cầu. Lợi ích của content-visibility không chỉ cắt bỏ đáng kể công việc kết xuất trong lần hiển thị trang ban đầu, mà còn bỏ qua công việc kết xuất đối với các phần tử ngoài màn hình khi DOM trang bị thay đổi do tương tác của người dùng.

Kết luận

Việc giảm kích thước DOM xuống chỉ còn những gì thực sự cần thiết là một cách hay để tối ưu hóa INP của trang web của bạn. Bằng cách này, bạn có thể giảm thời gian mà trình duyệt cần để thực hiện công việc bố cục và hiển thị khi DOM được cập nhật. Ngay cả khi không thể giảm đáng kể kích thước DOM, bạn vẫn có thể sử dụng một số kỹ thuật để tách riêng công việc kết xuất với cây con DOM, chẳng hạn như chứa CSS và thuộc tính CSS content-visibility.

Dù vậy, việc tạo ra một môi trường nơi giảm thiểu công việc kết xuất – cũng như giảm lượng công việc kết xuất mà trang của bạn thực hiện để phản hồi các tương tác – kết quả là trang web của bạn sẽ cảm thấy phản hồi nhanh hơn đối với người dùng khi họ tương tác với chúng. Điều đó có nghĩa là trang web của bạn sẽ có INP thấp hơn, từ đó mang lại trải nghiệm người dùng tốt hơn.

Hình ảnh chính từ Unsplash, của Louis Reed.