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ó ảnh hưởng đến tính tương tác nhiều 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 khác: khi bạn tạo một trang web, trang đó sẽ có một Mô hình đối tượng tài liệu (DOM). DOM đại diện cho cấu trúc HTML của trang và 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 của trình duyệt trong việc kết xuất một trang một cách nhanh chóng và hiệu quả. Nói chung, DOM càng lớn thì chi phí hiển thị ban đầu của trang đó càng cao và chi phí cập nhật quá trình hiển thị sau này trong vòng đời của trang cũng cao hơn.

Điều này sẽ gây ra vấn đề trong các trang có DOM rất lớn khi các hoạt động tương tác sửa đổi hoặc cập nhật DOM kích hoạt hoạt động bố cục tốn kém, ả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 chỉ số Lượt tương tác đến nội dung hiển thị tiếp theo (INP) của một trang; Nếu muốn một trang phản hồi nhanh chóng các hoạt động tương tác của người dùng, bạn cần đảm bảo kích thước DOM 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 là quá lớn khi vượt quá 1.400 nút. Lighthouse sẽ bắt đầu đưa ra cảnh báo khi DOM của một trang vượt quá 800 nút. Ví dụ: Lấy HTML sau:

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

Trong đoạn mã trên, có 4 phần tử DOM: phần tử <ul> và 3 phần tử con <li> của phần tử đó. Trang web của bạn chắc chắn sẽ có nhiều nút hơn thế này, vì vậy, điều quan trọng là bạn phải hiểu rõ những việc có thể làm để kiểm soát kích thước DOM, cũng như các chiến lược khác để tối ưu hoá hoạt động kết xuất sau khi bạn đã giảm kích thước DOM của một trang xuống mức 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 trang theo một số cách:

  1. Trong quá trình kết xuất ban đầu của trang. Khi CSS được áp dụng cho một trang, một cấu trúc tương tự như DOM (Mô hình đối tượng tài liệu) được gọi là Mô hình đối tượng CSS (CSSOM) sẽ được tạo. Khi bộ chọn CSS tăng độ cụ thể, CSSOM sẽ trở nên phức tạp hơn và cần nhiều thời gian hơn để chạy bố cục, tạo kiểu, kết hợp và vẽ công việc cần thiết để vẽ trang web lên màn hình. Công 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 hoạt động 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 DOM, công việc cần thiết để kết xuất bản cập nhật đó có thể dẫn đến bố cục, tạo kiểu, kết hợp và vẽ rất tốn kém. Như trường hợp kết xuất ban đầu của trang, việc tăng độ đặc hiệu của bộ chọn CSS có thể làm tăng công việc kết xuất khi các phần tử HTML được chèn vào DOM do kết quả của một lượt tương tác.
  3. Khi JavaScript truy vấn DOM, các tham chiếu đến phần tử DOM sẽ đượ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, thì 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 về một tác vụ dài do hoạt động kết xuất quá mức 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. Ngăn xếp lệnh gọi của tác 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ư giai đoạn trước khi hiển thị.
Một tác vụ dài như trong trình phân tích hiệu suất trong Công cụ cho nhà phát triển của Chrome. Thao tác dài xuất hiện là do chèn các phần tử DOM vào một DOM lớn thông qua JavaScript.

Tất cả những 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 hoạt động tương tác dẫn đến thay đổi đối với DOM, thì hoạt động đó có thể bắt đầu nhiều việc có thể góp phần làm cho INP trên một trang trở nên kém.

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

Bạn có thể đo 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 quy trình kiểm tra "Tránh kích thước DOM quá lớn" trong mục "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 là sử dụng bảng điều khiển JavaScript trong các công cụ dành cho nhà phát triển ở mọi trình duyệt chính. Để 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:

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ụ theo dõi hiệu suất. Khi sử dụng công cụ này, bạn có thể tương quan các thao tác bố cục và tạo kiểu (cùng với các khía cạnh khác về hiệu suất) cùng với kích thước DOM hiện tại.

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

Nếu kích thước DOM đang tiến gần đến ngưỡng cảnh báo kích thước DOM của Lighthouse hoặc hoàn toàn không đạt được, thì bước tiếp theo là tìm ra cách giảm kích thước DOM để cải thiện khả năng phản hồi của trang đối với hoạt động tương tác của người dùng, nhờ đó có thể cải thiện chỉ số INP của trang web.

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

Nếu đang lập hồ sơ cho một lượt 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ỳ phần nào của hoạt động trong trình phân tích tài nguyên được gắn nhãn "Recalculate Style" (Tính toán lại kiểu) và quan sát dữ liệu theo bối cảnh trong bảng điều khiển dưới cùng.

Ảnh chụp màn hình của hoạt động tính toán lại kiểu đã chọn 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. Ở trên cùng, bản ghi tương tác cho thấy một lượt tương tác nhấp và phần lớn thời gian được dùng để tính toán lại kiểu và thực hiện công việc trước khi vẽ. Ở dưới cùng, một bảng điều khiển sẽ cho biết thêm thông tin chi tiết về hoạt động đã chọn, trong đó báo cáo rằng 2.547 phần tử DOM đã bị ảnh hưởng.
Theo dõi số lượng phần tử bị ảnh hưởng trong DOM do kết quả của quá trình tính toán lại kiểu. Xin lưu ý rằng phần được tô bóng của lượt tương tác trong bản ghi lượt tương tác biểu thị phần thời lượng tương tác dài hơn 200 mili giây, đây là ngưỡng "tốt" được chỉ định cho INP.

Trong ảnh chụp màn hình ở trên, hãy lưu ý rằng việc tính toán lại kiểu của thành phần (khi được chọn) sẽ 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 cực đoan về ảnh hưởng của kích thước DOM đến hoạt động kết xuất trên một trang có nhiều phần tử DOM, nhưng thông tin chẩn đoán này 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ế thời gian cần thiết để khung hình tiếp theo hiển thị nhằm phản hồi một hoạt động 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 để tìm những 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 DOM. Một dấu hiệu cho thấy DOM của bạn có thể quá sâu 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ụ dành 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, có thể bạn sẽ đơn giản hoá được chúng bằng cách làm phẳng cấu trúc DOM. Việc này sẽ giảm số lượng phần tử DOM và có thể giúp bạn đơn giản hoá kiểu trang.

Độ sâu DOM cũng có thể là một triệu chứng của các 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ư những khung dựa trên JSX) yêu cầu bạn 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 những thành phần được gọi là mảnh. Các khung dựa trên thành phần cung cấp đoạn làm một tính năng bao gồm (nhưng không giới hạn ở) những khung sau:

Bằng cách sử dụng các mảnh trong khung bạn chọn, bạn có thể giảm độ sâu 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 các chế độ bố cục hiện đại (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 cố gắng 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ể, thì DOM vẫn có thể khá lớn và bắt đầu nhiều công việc kết xuất khi thay đổi để phản hồi các hoạt động tương tác của người dùng. Nếu gặp phải trường hợp này, 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 phương pháp bổ sung

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

Phương pháp này hữu ích cả trong quá trình tải ban đầu và có thể là cả sau đó. Đối với lần tải trang ban đầu, bạn sẽ thực hiện ít công việc kết xuất hơn ngay từ đầu, tức là tải trọng HTML ban đầu của bạn sẽ nhẹ hơn và kết xuất nhanh hơn. Điều này sẽ giúp các hoạt động tương tác trong khoảng thời gian quan trọng đó có nhiều cơ hội chạy hơn mà ít phải cạnh tranh sự chú ý của luồng chính.

Nếu có nhiều phần của trang ban đầu bị ẩn khi tải, thì điều này cũng có thể tăng tốc các hoạt động tương tác khác kích hoạt công việc kết xuất lại. Tuy nhiên, khi các lượt tương tác khác thêm nhiều nội dung vào DOM, công việc kết xuất 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ể phức tạp và có những điểm hạn chế riêng. Nếu đang đi theo hướng này, có thể bạn đang thực hiện các yêu cầu mạng để lấy dữ liệu nhằm điền sẵn vào HTML mà bạn dự định thêm vào trang để phản hồi một lượt tương tác của người dùng. Mặc dù các yêu cầu mạng đang diễn ra không được tính vào INP, nhưng điều này có thể làm tăng độ trễ cảm nhận. Nếu có thể, hãy cho thấy một biểu tượng 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 rằng có điều 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 bộ chọn trong CSS, trình duyệt phải duyệt qua cây DOM để hiểu cách thức và liệu những bộ chọn đó có áp dụng cho bố cục hiện tại hay không. Các bộ chọn này càng phức tạp thì trình duyệt càng phải thực hiện nhiều thao tác để thực hiện cả quá trình kết xuất ban đầu của trang, cũng như tăng số lần tính toán lại kiểu và bố cục nếu trang thay đổi do một lượt tương tác.

Sử 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ị các phần tử DOM ngoài màn hình một cách gián tiếp. Khi các phần tử tiếp cậ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ỉ giúp giảm đáng kể lượng công việc kết xuất trong quá trình kết xuất trang ban đầu, mà còn bỏ qua công việc kết xuất cho các phần tử ngoài màn hình khi DOM trang thay đổi do hoạt động tương tác của người dùng.

Kết luận

Giảm kích thước DOM chỉ còn những gì thực sự cần thiết là một cách hay để tối ưu hoá INP của trang web. Bằng cách này, bạn có thể giảm thời gian cần thiết để trình duyệt 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 hoạt động kết xuất thành một cây con DOM, chẳng hạn như tính năng CSS containment và thuộc tính CSS content-visibility.

Tuy nhiên, dù bạn thực hiện theo cách nào, việc tạo ra một môi trường 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 lượt tương tác) sẽ giúp trang web của bạn phản hồi nhanh hơn với người dùng khi họ tương tác với trang web. Điều đó có nghĩa là bạn sẽ có chỉ số INP thấp hơn cho trang web của mình, nhờ đó mang lại trải nghiệm người dùng tốt hơn.