DOMContentLoaded là gì? Giải mã sự kiện quan trọng trong JavaScript và tối ưu tốc độ tải trang

dom content loaded là gì

Sự kiện DOMContentLoaded là một trong những khái niệm nền tảng mà bất kỳ lập trình viên front-end nào cũng cần nắm vững. Khi người dùng truy cập một trang web, trình duyệt sẽ tải xuống và xử lý toàn bộ mã HTML, CSS, JavaScript. Hiểu đúng về DOM content loaded là gì sẽ giúp bạn kiểm soát thời điểm chạy script, cải thiện trải nghiệm người dùng và tối ưu hiệu suất tải trang. Bài viết này sẽ đi sâu vào bản chất, cơ chế hoạt động, so sánh với các sự kiện khác và hướng dẫn ứng dụng thực tế.

Khái niệm DOMContentLoaded – định nghĩa và bản chất

dom content loaded là gì - Hình 5

DOMContentLoaded là một sự kiện (event) trong JavaScript thuần, được kích hoạt ngay khi cây DOM (Document Object Model) của trang web đã được trình duyệt phân tích và xây dựng hoàn chỉnh từ mã HTML. Thời điểm này, trình duyệt đã đọc hết file HTML, tạo ra tất cả các node (thẻ) DOM từ đến các phần tử con. Tuy nhiên, các tài nguyên bên ngoài như hình ảnh, stylesheet, iframe, video… có thể chưa tải xong.

Bản chất của sự kiện này nằm ở chỗ nó cho phép các nhà phát triển can thiệp vào DOM ngay khi DOM sẵn sàng, mà không cần chờ đợi toàn bộ tài nguyên media tải xong. Điều này cực kỳ hữu ích để tăng tốc thời gian tương tác sớm (First Paint, Time to Interactive).

Cách trình duyệt kích hoạt DOMContentLoaded

Quy trình diễn ra như sau:

    • Trình duyệt tải file HTML và bắt đầu phân tích cú pháp (parsing).
    • Khi gặp thẻ <script> đồng bộ, quá trình parsing dừng lại, tải và thực thi script, sau đó parsing tiếp.
    • Sau khi parser hoàn thành việc xây dựng cây DOM từ đầu đến cuối, sự kiện DOMContentLoaded được kích hoạt ngay lập tức.
    • Nếu có thẻ <script defer>, script được tải song song nhưng thực thi sau khi parsing hoàn tất, trước DOMContentLoaded.
    • Nếu có thẻ <script async>, script tải và thực thi không cố định, có thể xảy ra trước hoặc sau sự kiện này.

    Đặc biệt, nếu stylesheet chưa được tải xong, trình duyệt vẫn kích hoạt DOMContentLoaded vì nó chỉ phụ thuộc vào DOM, không phụ thuộc vào CSSOM. Tuy nhiên, nếu script có lệnh document.write, điều này có thể làm chậm parsing và ảnh hưởng đến thời điểm kích hoạt.

    Phân biệt DOMContentLoaded với sự kiện load

    dom content loaded là gì - Hình 4

    Nhiều developer mới thường nhầm lẫn giữa DOMContentLoadedload. Cả hai đều là sự kiện của window/document, nhưng ý nghĩa hoàn toàn khác nhau.

    Tiêu chí DOMContentLoaded load
    Thời điểm kích hoạt Sau khi DOM parsing hoàn tất, các tài nguyên khác có thể chưa tải Sau khi tất cả tài nguyên (hình ảnh, CSS file, iframe, video) đã tải xong
    Tốc độ Nhanh hơn, thường chỉ vài mili giây sau khi HTML được phân tích xong Chậm hơn, phụ thuộc vào băng thông và kích thước tài nguyên
    Ứng dụng Thích hợp để chạy script thao tác DOM, thiết lập sự kiện, khởi tạo UI Thích hợp cho analytics, tracking, lazy load ảnh, hoặc code cần kích thước chính xác của ảnh/video
    Độ tin cậy với CSS Không đảm bảo stylesheet đã được tải hết, có thể gây “flash of unstyled content” nếu chạy script sớm Đảm bảo mọi thứ đã sẵn sàng, an toàn cho các thao tác liên quan đến layout

    Ví dụ thực tế: Nếu bạn đính kèm một script chạy trong sự kiện load, người dùng sẽ thấy trang trắng hoặc layout chưa hoàn chỉnh trong vài giây. Nếu dùng DOMContentLoaded, các tính năng tương tác cơ bản (menu, form validation, animation nhẹ) sẽ xuất hiện ngay, giúp trang “có vẻ” đã tải xong nhanh hơn.

    Tác động của async và defer đến DOMContentLoaded

    dom content loaded là gì - Hình 3

    Việc sử dụng thuộc tính async và defer trong thẻ script ảnh hưởng trực tiếp đến thời điểm DOMContentLoaded được kích hoạt.

    • Script không thuộc tính (blocking): Cản trở parsing, DOMContentLoaded bị trì hoãn cho đến khi script tải và thực thi xong.
    • Script defer: Tải song song với HTML parsing, nhưng thực thi theo thứ tự khai báo sau khi parsing hoàn tất. Sự kiện DOMContentLoaded chờ defer script thực thi xong.
    • Script async: Tải song song, thực thi ngay khi tải xong (bất kể parsing đã hoàn tất hay chưa). DOMContentLoaded không chờ script async, nhưng nếu script async hoàn thành trước khi parsing xong, nó có thể làm gián đoạn.

    Thực tiễn cho thấy, với các script không quan trọng (analytics, chat bot, quảng cáo), sử dụng async hoặc defer để không chặn sự kiện DOMContentLoaded là cách tối ưu hiệu suất. Các script quan trọng cho UI nên được đặt ở cuối body hoặc dùng defer nhằm đảm bảo DOM sẵn sàng trước khi thực thi.

    Lợi ích của việc tận dụng DOMContentLoaded

    dom content loaded là gì - Hình 2

    Sử dụng đúng sự kiện này giúp cải thiện trải nghiệm người dùng rõ rệt:

    • Tăng tốc tương tác sớm: Người dùng có thể click, nhập liệu, xem menu ngay cả khi ảnh chưa tải hết. Điều này cải thiện chỉ số Time to Interactive (TTI) và First Input Delay (FID).
    • Cải thiện SEO Core Web Vitals: Các công cụ tìm kiếm như Google đánh giá cao các trang có DOMContentLoaded nhanh vì nó thể hiện tốc độ xử lý mã nguồn và sẵn sàng hiển thị nội dung.
    • Tránh lỗi undefined selector: Khi chạy JavaScript trước khi DOM sẵn sàng, bạn sẽ nhận lỗi “Cannot read property ‘addEventListener’ of null”. Dùng DOMContentLoaded đảm bảo các node DOM tồn tại trước khi thao tác.
  • Giảm thiểu flicker: Kết hợp với CSS đúng cách,

    Không. DOMContentLoaded chỉ phụ thuộc vào DOM parsing, không phụ thuộc vào CSSOM. Tuy nhiên, nếu có script chèn trực tiếp (inline script) mà truy cập style của phần tử, CSSOM có thể chưa sẵn sàng, dẫn đến tính toán sai. Vì thế, hãy đặt các script liên quan đến style sau khi load xong CSS hoặc trong sự kiện load.

    Làm thế nào để kiểm tra thời điểm DOMContentLoaded trên trình duyệt?

    Mở Chrome DevTools, vào tab Performance, nhấn Record, tải lại trang. Tìm dòng “DOMContentLoaded” trên timeline. Bạn cũng có thể vào tab Console và gõ “performance.getEntriesByType(‘navigation’).domContentLoadedEventEnd” để lấy giá trị chính xác.

    DOMContentLoaded có khả dụng trên tất cả trình duyệt không?

    Có. Sự kiện này được hỗ trợ từ Internet Explorer 9 trở lên, Chrome, Firefox, Safari, Edge. Trên IE8 trở xuống, bạn phải dùng document.readyState hoặc thư viện jQuery để tương thích. Hiện nay, gần 99% người dùng đều dùng trình duyệt hỗ trợ.

    Sự khác biệt giữa document.addEventListener(‘DOMContentLoaded’,…) và window.addEventListener(‘DOMContentLoaded’,…) là gì?

    Trong thực tế, cả hai đều hoạt động vì sự kiện này được phát trên document và bubble lên window. Tuy nhiên, chuẩn khuyến nghị lắng nghe trên document. Dùng window có thể dẫn đến hành vi khác thường trong một số trường hợp hiếm gặp (ví dụ: worker).

    Có nên lồng nhiều lệnh addEventListener cho cùng sự kiện DOMContentLoaded không?

    Hoàn toàn được. Mỗi callback sẽ được thực thi theo thứ tự đăng ký. Đây là cách tốt để phân tách logic mà không ảnh hưởng lẫn nhau.

    Điều gì xảy ra nếu script được thêm vào sau khi DOMContentLoaded đã kích hoạt?

    Nếu bạn chèn script động (document.createElement(‘script’)) sau khi sự kiện đã xảy ra, callback của sự kiện đó sẽ không được chạy. Lúc này, bạn cần kiểm tra document.readyState === ‘complete’ hoặc ‘interactive’ để quyết định thực thi ngay lập tức.

    Kết luận

    dom content loaded là gì - Hình 1

    Hiểu rõ DOM content loaded là gì là bước đệm vững chắc để làm chủ hiệu suất web. Sự kiện này cho phép bạn can thiệp vào giao diện sớm nhất có thể mà vẫn an toàn, giúp website trở nên nhanh nhạy và thân thiện với người dùng cũng như công cụ tìm kiếm.

    Trong quá trình phát triển, hãy luôn đặt câu hỏi: “Tác vụ này có thực sự cần chờ load hết ảnh không?” Nếu câu trả lời là không, hãy chạy nó trong DOMContentLoaded. Kết hợp với chiến lược tải script thông minh (defer, async), bạn sẽ thấy sự khác biệt rõ rệt về tốc độ và trải nghiệm. Đừng xem nhẹ sự kiện nhỏ này – nó chính là chìa khóa để xây dựng web performance tối ưu.

Bài viết cùng chủ đề:

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *