v147 · html · in developer trial
Lazy loading for video and audio elements
Adds the loading attribute to <video> and <audio> elements, letting browsers defer media resource loading until the element is near the viewport — the same mechanism already available for <img> and <iframe>.
This page records the Chrome 147 milestone, where the feature was in developer trial behind chrome://flags/#enable-experimental-web-platform-features. Both blockers noted at the time have since resolved: the spec change, WHATWG HTML PR #11980, merged on 2026-03-23 into the HTML living standard, and the attribute shipped on by default: partially in Chrome 148 (not honored for <source> children, crbug.com/514611050) and fully in Chrome 150, per BCD; the LazyLoadVideoAndAudio entry in runtime_enabled_features.json5 is status: "stable" (verified 2026-09-20). Firefox and Safari have not shipped it, so cross-browser code still needs the feature-detect fallback.
at a glance
| Status in Chrome 147 | In developer trial (behind a flag) — the milestone=147 listing position this page records. Shipped by default from Chrome 148 (fully from 150) — see the compat table |
|---|---|
| Flag (147) | chrome://flags/#enable-experimental-web-platform-features; the runtime feature LazyLoadVideoAndAudio is now stable (flag registry, 2026-09-20) |
| New attribute | loading on <video> and <audio>, reflected by the HTMLMediaElement.loading IDL attribute (HTML living standard — media elements) |
| Values | eager (default) · lazy — a standard lazy loading attribute |
| Standards position | Firefox: Positive (mozilla/standards-positions #1325) · Safari: Support (WebKit/standards-positions #586) — neither shipped as of 2026-09-20 (BCD) |
| Spec | WHATWG HTML PR #11980 (merged 2026-03-23) → HTML living standard |
| Chromium bug | issues.chromium.org/issues/469111735 |
| ChromeStatus | 5200068565139456 — Lazy loading for video and audio elements (API record) |
syntax
Content-attribute grammar — a standard lazy loading attribute, defined once in the HTML living standard and now used by <img>, <iframe>, <video>, and <audio> (quoted verbatim, fetched 2026-09-20): “A lazy loading attribute is an enumerated attribute with the following keywords and states: lazy — Lazy — used to defer fetching a resource until some conditions are met; eager — Eager — used to fetch a resource immediately; the default state.” A missing or unrecognized value therefore behaves as eager.
<video loading="lazy"> … </video>
<audio loading="eager"> … </audio> <!-- eager is the default state -->
DOM reflection (HTML living standard — media elements): HTMLMediaElement gains attribute DOMString loading, and “the loading IDL attribute must reflect the loading content attribute, limited to only known values” — so reading video.loading yields "eager" or "lazy", and assigning it sets the content attribute:
const video = document.querySelector("video");
video.loading = "lazy"; // same as setting the attribute in markup
console.log(video.loading); // "lazy"
Source: HTML § lazy loading attributes; HTML § media elements; PR #11980
why it exists
Since Chrome 76, <img loading="lazy"> and <iframe loading="lazy"> have let browsers skip fetching off-screen resources until the user scrolls close to them. The same pattern has never applied to <video> and <audio>, which start loading their source files as soon as the parser encounters them regardless of position on the page. Long-form pages with multiple embedded videos pay a large up-front network cost even when most users never scroll to those media elements. The loading attribute on media elements closes this gap and aligns behaviour across all embeddable resources.
the attribute
| Attribute | loading |
|---|---|
| Elements | <video>, <audio> |
loading="eager" | Default. Load the resource immediately, same as current behavior without the attribute. |
loading="lazy" | Defer resource loading until the element is within the browser's lazy-loading distance threshold from the viewport. The exact threshold is browser-defined and may vary by network conditions. |
<source> caveat | In Chrome 148–149 the attribute was not honored when the media resource came from <source> children (only from a src attribute) — fixed in Chrome 150 (crbug.com/514611050, recorded in BCD) |
When loading="lazy" is set:
| Network request | Deferred until the element enters the lazy-load intersection zone. |
|---|---|
preload interaction | A preload="none" hint continues to suppress loading. loading="lazy" takes effect only when the browser would otherwise begin fetching. |
| Autoplay | With autoplay and loading="lazy", the browser defers playback and any network requests autoplay introduces until the lazy-load resumption steps run. Playback still depends on the usual autoplay eligibility and policy checks. |
JavaScript .play() | If the call is allowed, .play() invokes pending lazy-load resumption steps before its internal play steps, so it can start loading before viewport intersection. The returned promise can still reject (for example, with NotAllowedError). |
<video poster> | A lazy video also defers loading its poster image until its lazy-load resumption steps run. |
example
Basic lazy video
<video loading="lazy" controls>
<source src="feature-demo.mp4" type="video/mp4">
<source src="feature-demo.webm" type="video/webm">
</video>
Lazy audio
<audio loading="lazy" controls>
<source src="podcast-episode.mp3" type="audio/mpeg">
<source src="podcast-episode.ogg" type="audio/ogg">
</audio>
Combining with preload
<!-- Best practice for a long page with many videos:
lazy defers fetching; preload="metadata" limits initial load to just
duration/dimensions once the element enters the threshold zone. -->
<video loading="lazy" preload="metadata" controls>
<source src="explainer.mp4" type="video/mp4">
</video>
Detecting support
const supportsLazyMedia = 'loading' in HTMLVideoElement.prototype;
if (!supportsLazyMedia) {
// Fall back to IntersectionObserver-based lazy loading
}
browser compatibility
Per-version data from BCD html/elements/video.json and audio.json (identical rows for both elements, and for the HTMLMediaElement.loading reflection), verified 2026-09-20:
| Browser | loading on <video>/<audio> | Notes |
|---|---|---|
| Chrome | 150 (full) · 148–149 partial | 148–149: not supported for <source> children (crbug 514611050); Chrome 147: dev trial behind a flag (this page’s milestone) |
| Edge | Mirrors Chrome | BCD "edge": "mirror" |
| Firefox | Not shipped | Implementation tracked at bugzil.la/2005072; position Positive (#1325) |
| Safari | Not shipped | Implementation tracked at webkit.org/b/303995; position Support (#586) |
Baseline: limited availability per the loading-lazy-media web-feature on webstatus.dev (queried 2026-09-20) — Chromium-only so far.
security and privacy
The attribute adds no new capability: deferred requests are the same media fetches the element would make anyway, under the same CORS and content-security rules. The one observable property is inherent to all lazy loading attributes: because the fetch fires when the element nears the viewport, its timing reveals approximate scroll position to the server hosting the media — exactly as <img loading="lazy"> has since Chrome 76. Pages that consider scroll behavior sensitive should not gate third-party-hosted media on it. Nothing else changes: no new headers, no new origins, no persistent state.
see also
- chromestatus — Lazy loading for video and audio elements (5200068565139456) (API record)
- WHATWG HTML PR #11980 — the spec change (merged 2026-03-23), now in the HTML living standard
- MDN — <video> (now documents the
loadingattribute, verified 2026-09-20) - Scott Jehl: Lazy loading media elements — background reading by the spec PR’s author
- Chromium bug — issue 469111735
- chrome-platform-showcase: Lazy loading for video and audio demos (five concept demos, route 200)