Document lifecycle (lab)
Lab document lifecycle: DOM interactive, DOM complete, load event.
At a glance the headline numbers for Document lifecycle (lab)
Lab document lifecycle: DOM interactive, DOM complete, load event.
The typical page reaches DOM interactive after 384ms in the lab.
Distribution & median LCP site count and median LCP at each level of document lifecycle (lab) — dom interactive
Passing LCP by document lifecycle (lab) — dom interactive which level passes the LCP most often
Document lifecycle (lab) — dom interactive 384ms. p75 859ms. p99 12.4s. At the low end (0–249ms): LCP 1.2s. At the high end (2000+ms): LCP 2.5s. computed
Why this matters for the Core Web Vitals, and where to start fixing it
The document lifecycle is the old way of measuring pages, and it still says useful things. DOM interactive marks the HTML fully parsed. DOM complete waits for the subresources. The load event is the official end of loading, and everything that listens for it (analytics, widgets, third-party tags) starts there.
A long gap between interactive and complete means resource weight, not markup. These milestones do not map onto user experience the way the vitals do, which is why they were replaced. But a page with a slow lifecycle does not produce fast vitals.
How does this affect the Core Web Vitals?
Document lifecycle (lab) correlates with the LCP. Where the DOM interactive is low, 90% of sites pass the LCP. Where it is high, 50% do. The decline is gradual. There is no point where sites suddenly start failing.
Chrome field data from 189,915 sites, representing millions of real page loads. How we measured.
Live queries (4) — admin only
SELECT COUNT(*) AS count,
quantile_disc(m.synthetic.document.dom_interactive, 0.10) AS p10,
quantile_disc(m.synthetic.document.dom_interactive, 0.25) AS p25,
quantile_disc(m.synthetic.document.dom_interactive, 0.50) AS p50,
quantile_disc(m.synthetic.document.dom_interactive, 0.75) AS p75,
quantile_disc(m.synthetic.document.dom_interactive, 0.90) AS p90,
quantile_disc(m.synthetic.document.dom_interactive, 0.99) AS p99
FROM sites WHERE m.synthetic.document.dom_interactive IS NOT NULL;
SELECT CASE WHEN m.synthetic.document.dom_interactive >= 0 AND m.synthetic.document.dom_interactive < 250 THEN 0 WHEN m.synthetic.document.dom_interactive >= 250 AND m.synthetic.document.dom_interactive < 500 THEN 1 WHEN m.synthetic.document.dom_interactive >= 500 AND m.synthetic.document.dom_interactive < 750 THEN 2 WHEN m.synthetic.document.dom_interactive >= 750 AND m.synthetic.document.dom_interactive < 1000 THEN 3 WHEN m.synthetic.document.dom_interactive >= 1000 AND m.synthetic.document.dom_interactive < 1250 THEN 4 WHEN m.synthetic.document.dom_interactive >= 1250 AND m.synthetic.document.dom_interactive < 1500 THEN 5 WHEN m.synthetic.document.dom_interactive >= 1500 AND m.synthetic.document.dom_interactive < 1750 THEN 6 WHEN m.synthetic.document.dom_interactive >= 1750 AND m.synthetic.document.dom_interactive < 2000 THEN 7 WHEN m.synthetic.document.dom_interactive >= 2000 THEN 8 END AS bucket_idx, COUNT(*) AS n,
quantile_disc(crux."all".lcp, 0.5) AS median,
COUNT(*) FILTER (WHERE crux."all".lcp IS NOT NULL AND crux."all".lcp <= 2500) * 1.0 / NULLIF(COUNT(*) FILTER (WHERE crux."all".lcp IS NOT NULL), 0) AS good_pct
FROM sites WHERE m.synthetic.document.dom_interactive IS NOT NULL GROUP BY bucket_idx;
SELECT COUNT(*) AS count,
quantile_disc(m.synthetic.document.dom_complete, 0.10) AS p10,
quantile_disc(m.synthetic.document.dom_complete, 0.25) AS p25,
quantile_disc(m.synthetic.document.dom_complete, 0.50) AS p50,
quantile_disc(m.synthetic.document.dom_complete, 0.75) AS p75,
quantile_disc(m.synthetic.document.dom_complete, 0.90) AS p90,
quantile_disc(m.synthetic.document.dom_complete, 0.99) AS p99
FROM sites WHERE m.synthetic.document.dom_complete IS NOT NULL;
SELECT COUNT(*) AS count,
quantile_disc(m.synthetic.document.load, 0.10) AS p10,
quantile_disc(m.synthetic.document.load, 0.25) AS p25,
quantile_disc(m.synthetic.document.load, 0.50) AS p50,
quantile_disc(m.synthetic.document.load, 0.75) AS p75,
quantile_disc(m.synthetic.document.load, 0.90) AS p90,
quantile_disc(m.synthetic.document.load, 0.99) AS p99
FROM sites WHERE m.synthetic.document.load IS NOT NULL;