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

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.
- 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.
- 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

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.
Đặ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

Nhiều developer mới thường nhầm lẫn giữa DOMContentLoaded và load. 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

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.
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

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:
- WooCommerce Add to Cart JavaScript Lỗi: Nguyên Nhân, Cách Khắc Phục Toàn Diện
- WordPress GD Library Lỗi: Nguyên Nhân Và Cách Khắc Phục Hoàn Chỉnh
- Hướng dẫn chi tiết cách tìm Cluster Keywords với Ahrefs từ A đến Z
- Theme WordPress theme.json là gì? Hướng dẫn toàn diện từ A đến Z cho người mới bắt đầu
- WordPress Email Không Hoạt Động: Nguyên Nhân Và Cách Khắc Phục Chi Tiết
















