Kích thước DOM lớn có nhiều ảnh hưởng đến khả năng tương tác hơn so với 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 để giải quyết vấn đề này: khi bạn tạo một trang web, trang đó sẽ có Mô hình đối tượng tài liệu (DOM). DOM đại diện cho cấu trúc HTML trên trang của bạn, đồng thời cấp cho JavaScript và CSS quyền truy cập vào cấu trúc và nội dung của trang.
Tuy nhiên, vấn đề xảy ra là kích thước của DOM ảnh hưởng đến khả năng hiển thị một trang nhanh chóng và hiệu quả của trình duyệt. Nói chung, DOM càng lớn thì càng tiêu tốn nhiều chi phí cho việc hiển thị trang đó và cập nhật kết xuất sau này trong vòng đời của trang.
Điều này sẽ trở thành vấn đề trê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 DOM kích hoạt công việc 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 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 tương tác của người dùng thì điều quan trọng là phải đảm bảo kích thước DOM của bạn chỉ lớn khi cần.
Khi nào DOM của một trang quá lớn?
Theo Lighthouse, kích thước DOM của một trang 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 đây 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ó bốn phần tử DOM: phần tử <ul>
và ba 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 thế 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 hoá công việc hiển thị sau khi bạn nhậ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:
- Trong lần hiển thị 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 được gọi là Mô hình đối tượng CSS (CSSOM) sẽ được tạo. Khi bộ chọn CSS tăng lên về 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 bố cục, tạo kiểu, kết hợp và vẽ cần thiết nhằm 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 các lượt tương tác xảy ra sớm trong quá trình tải trang.
- 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 việc bố cục, tạo kiểu, kết hợp và vẽ rất tốn kém. Như trong trường hợp lần hiển thị ban đầu của trang, sự gia tăng tính cụ thể của bộ chọn CSS có thể thêm vào công việc hiển thị khi các phần tử HTML được chèn vào DOM do kết quả của một tương tác.
- 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, thì chi phí bộ nhớ có thể đáng kể nếu kết quả trả về nhiều phần tử DOM.
![Ảnh chụp màn hình một tác vụ mất nhiều thời gian do 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ư vẽ trước.](https://web.developers.google.cn/static/articles/dom-size-and-interactivity/image/a-screenshot-a-long-task-a768ec4a643a9.png?authuser=5&hl=vi)
Tất cả các thành phần nêu trên đề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ì có thể bắt đầu rất nhiều việc có thể góp phần vào INP kém trên trang.
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 kiểm tra, số liệu thống kê về DOM của trang hiện tại sẽ nằm trong "Tránh kích thước DOM quá mức" trong mục "Chẩn đoán" tiêu đề. 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.
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 đây 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 trong thời gian thực, bạn cũng có thể sử dụng công cụ theo dõi 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à tạo kiểu (cũng như các khía cạnh hiệu suất khác) 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 khác nhau của hiệu suất trang có thể được theo dõi liên tục trong suốt thời gian hoạt động 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à các lần tính toán lại kiểu trên mỗi phần đang được tích cực theo dõi.](https://web.developers.google.cn/static/articles/dom-size-and-interactivity/image/a-screenshot-the-perform-d46dd7f32a5de.png?authuser=5&hl=vi)
Nếu kích thước của DOM sắp đạt đến ngưỡng cảnh báo của kích thước Lighthouse DOM – hoặc hoàn toàn không thành công – thì bước tiếp theo là tìm ra cách giảm kích thước của DOM để cải thiện khả năng phản hồi của trang của bạn với các tương tác của người dùng để INP của trang web của bạn có thể cải thiện.
Làm cách nào để đo lường số lượng các phần tử DOM bị ảnh hưởng bởi một lượt tương tác?
Nếu bạn đang phân tích một tương tác chậm trong phòng thí nghiệm mà bạn nghi ngờ có liên quan đến kích thước DOM của trang, bạn có thể tìm ra có bao nhiêu phần tử DOM bị ảnh hưởng bằng cách chọn bất kỳ phần hoạt động nào trong trình phân tích có nhãn "Tính toán lại kiểu" và quan sát dữ liệu theo bối cảnh ở bảng điều khiển dưới cùng.
![Ảnh chụp màn hình 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ụ cho nhà phát triển của Chrome. Ở trên cùng, bản theo dõi lượt tương tác cho thấy một lượt tương tác với lượt nhấp và phần lớn công việc được dành để tính toán lại kiểu và vẽ lại trước. Ở dưới cùng, một bảng điều khiển hiện 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.](https://web.developers.google.cn/static/articles/dom-size-and-interactivity/image/a-screenshot-selected-st-9a6c0cc217aa3.png?authuser=5&hl=vi)
Trong ảnh chụp màn hình ở trên, hãy quan sát thấy rằng việc tính toán lại kiểu của tác phẩm (khi được chọn) cho thấy 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ề ảnh hưởng của kích thước DOM đến việc hiển thị hoạt động trên một trang có nhiều phần tử DOM, 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ế trong thời gian khung tiếp theo hiển thị theo 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 trên trang web của bạn để xem có đánh dấu không cần thiết hay không, cách chính để giảm kích thước DOM là giảm chiều sâu của DOM. Một tín hiệu cho thấy DOM của bạn có thể sâu không cần thiết là khi bạn thấy mã đánh dấu trông giống như thế này trong thẻ Phần tử trong công cụ cho nhà phát triển của 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à 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 phải lồng nhiều thành phần trong một vùng chứa mẹ.
Tuy nhiên, có nhiều khung cho phép bạn tránh lồng ghép 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 các 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 hạng mục sau:
Bằng cách sử dụng các phân đoạn trong khung mà bạn chọn, bạn có thể giảm chiều sâu của DOM. Nếu lo ngại về tác động của cấu trúc DOM làm phẳng đố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 hơn (và nhanh hơn) như flexbox hoặc grid.
Các chiến lược khác nên cân nhắc
Ngay cả khi bạn gặp khó khăn trong việ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 của bạn nhỏ nhất có thể, nó vẫn có thể khá lớn và bắt đầu nhiều công việc kết xuất vì 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, 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 hình ảnh.
Cân nhắc phương pháp bổ sung
Bạn có thể đang ở vị trí mà ban đầu, người dùng không nhìn thấy phần lớn của trang khi trang hiển thị lần đầu tiên. Đâ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 các phần này 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í cả sau đó. Đối với lần tải trang ban đầu, bạn sẽ thực hiện trước ít công việc kết xuất hơn, có nghĩa là tải trọng HTML ban đầu của bạn sẽ nhẹ hơn và sẽ hiển thị nhanh hơn. Nhờ đó, các lượt tương tác trong giai đoạn quan trọng đó sẽ có nhiều cơ hội chạy hơn mà ít phải cạnh tranh hơn để thu hút sự chú ý của chuỗi chính.
Nếu ban đầu bạn có nhiều phần của trang bị ẩn khi tải, điều này cũng có thể tăng tốc các 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 hoạt động tương tác khác bổ sung nhiều hơn 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ể phức tạp và cũng có những đánh đổi riêng. Nếu chọn cách này, có thể bạn sẽ tạo các yêu cầu mạng để lấy dữ liệu nhằm điền sẵ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 bay 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 rằng có điều gì đó đang xảy ra.
Hạn chế độ phức tạp của bộ chọn CSS
Khi trình duyệt phân tích cú pháp bộ chọn trong CSS của bạn, trình duyệt phải di chuyển qua cây DOM để hiểu cách thức—và nếu—các bộ chọn đó áp dụng cho bố cục hiện tại. 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 hơn để thực hiện cả việc hiển thị ban đầu cho trang, cũng như tăng các tính toán lại kiểu và bố cục nếu trang thay đổi do kết quả của mộ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ị từng phần các phần tử DOM ngoài màn hình. 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ỉ loại bỏ một lượng đá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 thay đổi do sự tương tác của người dùng.
Kết luận
Giảm kích thước DOM của bạn xuống 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 của bạn. Nhờ vậy, bạn có thể giảm lượng thời gian mà trình duyệt cần để thực hiện công việc bố cục và kết xuất khi DOM được cập nhật. Ngay cả khi bạn không thể giảm đáng kể kích thước DOM, có một số kỹ thuật bạn có thể sử dụng để tách riêng công việc kết xuất với cây con DOM, chẳng hạn như vùng chứa CSS và thuộc tính CSS content-visibility
.
Tuy nhiên, nếu bạn thực hiện việc này, việc tạo một môi trường trong đó công việc kết xuất được giảm thiểu — cũng như giảm lượng công việc hiển thị mà trang của bạn thực hiện để phản hồi 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 cho 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, đồng nghĩa với việc mang lại trải nghiệm tốt hơn cho người dùng.
Hình ảnh chính trong Unsplash của Louis Reed.