How a Browser Decides a Page Is Ready, and Why Your Metric Disagrees
When you navigate to a webpage, how do browsers determine when it's ready? After all, web browsers have a well defined moment in time when they say they are done loading a…

What’s in this piece
When you navigate to a webpage, how do browsers determine when it's ready? After all, web browsers have a well defined moment in time when they say they are done loading a page's resources, but in practice this is often not the same as when the main content users are waiting on becomes available. That mismatch—that mismatch between a page being "done" and the content being "ready"—can be confusing. But it all comes down to how browser-made milestones are different from how we measure readiness for users.
Browser Milestones
When your browser loads a page, it goes through a series of readability states defined in the Document.readyState property. According to, these states answer the well-defined engineering question of how much of the document tree has been parsed or resources fetched. But the milestones don't measure when the most important content is rendered for the user.
The readyState property can have three values:
loading: the browser is still parsing the HTML.interactive: the document has been parsed, but sub-resources (images, scripts, etc) may still be loading.complete: the document and all sub-resources have finished loading, and the window.load event is about to fire.
When the readyState changes, a readystatechange event fires on the document object. But the browser also signals when document parsing and scripts are done with the separate DOMContentLoaded event, and when all content is fetched with load. And these two have subtle differences:
In the interactive state, once deferred and module scripts have executed, the DOMContentLoaded event fires. The longer complete state means not just the document, but also sub-resources like images and iframes are fully loaded, and the load event is about to fire.
But crucially, the document.readyState property and the events that go along side it are not designed to answer the question of when a page is "ready" for the user – only the browser. They mark internal points of parsing and fetching, not usefulness.
The Version of “Ready” That Doesn’t Mean Ready
Things get messier with the load event. This is where a lot of misconceptions come in. Developers coming from an older large-scale web dev or object-oriented background often expect the window load event to mark the page as fully loaded and ready. And loading is what the web browser 'engine' is doing behind the scenes.
But modern web developers know different. The load event should be used only to detect a fully-loaded page, because it measures parsing and loading, not content delivery. Mozilla says it is a common mistake to use load where DOMContentLoaded would be more appropriate. This is not the case.
If your site depends on measuring when content is ready for the user to interact, don't default to load. Modern sites often ship with inline rendering that tracks ready states. Some developers may suggest to hook into one of the document.readyState-based events or even set up an event listener for DOMContentLoaded before window.load.
What about timing APIs though? They still sound like they default to legacy timing practices. Navigation Timing Level 2 has properties like loadEventStart (the time immediately before the load event fires) and loadEventEnd (the time when the load event ends).
If you're pulling legacy APIs, MDN recommends using PerformanceNavigationTiming.loadEventStart and PerformanceNavigationTiming.loadEventEnd, which are part of Navigation Timing API. All of these APIs are about page load, but the developer burden is now on user-advocates to break down the difference between load metrics and rendering.
The User-Centric Metric Shift
Since 2019, Google has moved web developers to focus on Core Web Vitals for page performance, shifting conversation away from old-fashioned loading milestones.
Largest Contentful Paint (LCP) in particular measures how quickly the most significant content element loads, not like load based on parsing and fetching all subresources. The Largest Contentful Paint metric measures the render time of the largest image or text block element relative to when the page first started loading. Essentially, it indicates when a user first sees something that matters.
LCP proximal loading helps us zoom out and make performance about human experiences instead of technical limits. In an era of all-in-one CSS, JS AND HTML frames falsely inflating loading times or just unnecessary bloat, user-centric metrics help us test page performance and user experience in terms of what matters to them, not just what happens in the browser's tiered internal processes.
What Does "Ready" Mean to a User
But here are signs you should be ready on the subject
For users, "ready" means the main content they're there to view is accessible. It means the info architecture: painstaking navigation menus are landing, the hero image is loaded, it means first drawn elements come together into a structure they can interact with or read. Not just therapeutic subresource loading.
The difference between an "interactive" page state defined by browser, meaning all scripts are available (even modules still downloading), and a fully loaded page where load happens, shows how much browsers have traditionally optimized for themselves, not user expectations. But modern core web vitals is a shift in power, from browser parsing to user interaction, from parsing completion to visible content.
DOMContentLoaded and timing APIs have their places. But as the web gets richer, and as we accustom ourselves to buoyant content and more client-side delivery, molds get stale. Page load metrics are crucial for debugging, but user behavior to guide long-term health.
- 01Web & Browsers
How Online Gaming Changed the Way We Interact with Digital Content
Online games are now part of daily life. We play on phones, tablets, laptops, and game consoles. We do not just look at a screen anymore. We touch, tap, speak, and…
- 02Web & Browsers
What user-select: none Really Does, and the Accessibility Bill It Runs Up
The CSS user-select property sets whether the user can select text with their mouse or keyboard. At none, it is intended to block direct text selection by the user. But…
- 03Web & Browsers
The Clipboard in the Browser: What a Page May Read, Write and Ask For
Access to the clipboard is governed by a split between read and write, with reading being gated more tightly than writing. The Clipboard API Gives pages the ability to access…
- 04Web & Browsers
Content Security Policy From Scratch, Without Breaking Your Own Site
Roll out a content security policy (CSP) and immediately block vital inline scripts, and you deserve every broken site you break. Take the proper step of deploying in…



