DOMContentLoaded vs. Load Event β Definition and Differences
Compare the two page lifecycle events: what each waits for, why the gap can be large, and which to use as a navigation condition in automation.
Both events mark a stage of page loading, and choosing between them is one of the most consequential decisions in browser automation β it determines whether a script waits far too long or acts far too early.
1. What Each Waits For
| Event | Fires when | Still pending |
|---|---|---|
DOMContentLoaded |
The HTML is parsed and the DOM is built | Images, stylesheets, fonts, iframes, async data |
load |
Every subresource has finished | Anything fetched by scripts afterwards |
The first is about document structure; the second about resource completion.
2. Why the Gap Can Be Enormous
On a media-heavy page the difference is easily several seconds β images, fonts, advertisements, and third-party embeds all delay load while contributing nothing to the content most scripts want.
Worse, pages with long-polling connections, streaming media, or persistently open resources may never fire load at all within a reasonable timeout.
3. Neither Guarantees Your Data Exists
This is the point most often missed. On a client-rendered page, content arrives from a fetch made after parsing, so:
DOMContentLoadedfires with an empty container.loadmay fire before the data request completes.
Both events describe document and resource lifecycle, not application state.
4. What to Use in Automation
The reliable pattern is to navigate with the cheap condition and then wait for evidence of the content:
page.goto(url, wait_until="domcontentloaded")
page.wait_for_selector("article.product") # the actual evidence
Waiting on a selector, a network response, or an element count proves the data arrived. Waiting on a lifecycle event proves only that a stage passed.
5. Network Idle Is Not the Answer Either
Waiting for network quiet seems appealing and is unreliable in practice: analytics beacons, polling, and persistent connections keep traffic flowing, so the condition either never holds or holds only after a long delay.
Use it, if at all, for pages known to go quiet β never as a general default.
6. Practical Guidance
- Navigate with
domcontentloadedas the default. - Wait explicitly on the element or response the task needs.
- Block images, fonts, and analytics when only text matters.
- Avoid fixed sleeps; they are either too short or wasteful.
- Set an explicit timeout and let failure be loud.
7. For Performance Measurement
The two events remain meaningful when measuring pages rather than scraping them: the gap between them quantifies how much subresource weight a page carries, and modern metrics build on the same lifecycle to describe perceived load.
8. Summary
DOMContentLoaded fires when the document is parsed; load fires when every subresource has finished, which can be much later or never.
Neither proves your data exists. Navigate with the earlier event and then wait on a condition that demonstrates the content is present β that single habit removes most flakiness from browser automation.