If you have videos on your Shopify store, you can improve your page's user experience and overall largest contentful paint (LCP) metric by using Liquid's new video_tag lazy loading option. Videos (and their poster images) outside the user's viewport won't take up valuable bandwidth that the browser needs to render the critical path.
Videos are big. We know that. We might spend hours resizing and compressing them in Handbrake or FFMPEG to get them down to a usable size, and even then they typically dwarf all of the other assets on your page combined. No matter how well you optimize them, putting one or more videos on your page will have a detrimental effect on your core web vitals, which is why we covered approaches to improving load times in our blog post Fast video banners that work on every device.
In that post we mentioned native video lazy loading as a future solution, but as of Chrome 148 (with an important bug fix in Chrome 150), it's here, and we've already shipped code to take advantage of it.
Chrome added native support for loading="lazy" on <video> elements, and Shopify's video_tag Liquid filter now sets it automatically for videos in sections further down the page. This is the same automatic behavior image_tag has had for years. If you use video_tag and don't set loading yourself, below-the-fold videos defer their download until the shopper scrolls near them.
No theme changes required.
The real user measurement results are in Jump to heading
We rolled this out in July 2026 and measured the effect in real user monitoring. Across pages that contain a video file:
- 75% fewer page views load video up front. The share of page views that actually downloaded a video file dropped from 18.5% to 4.6%. Videos that shoppers never scroll to now never download.
- 78% less video data per page view. That's 1.23MB less video transferred per page view, on average.
On stores where videos used to load eagerly, Chrome now loads far fewer videos on initial page load and transfers far fewer video bytes. This improves storefront performance, especially on media-heavy themes, and it happened without theme developers changing a line of code.
Why video is a performance problem Jump to heading
About 20% of Shopify storefronts use a <video> element on their homepage (HTTP Archive, April 2026 crawl, roughly 670,000 mobile pages). When a video is present, it dominates the page weight. The median store with homepage video serves 12.5MB of video, which is 75% of total page weight on mobile. Over 80,000 mobile pages ship more than 5MB of video.
That weight has a direct, measurable cost, but not the one you might expect. The metric it hurts is Speed Index (SI), not Largest Contentful Paint (LCP):
| Video weight | Pages (mobile) | Median Speed Index (mobile) |
|---|---|---|
| No video | 565,145 | 7,243ms |
| Under 500KB | 1,125 | 10,954ms |
| 500KB–2MB | 5,387 | 10,962ms |
| 2MB–5MB | 17,007 | 12,030ms |
| Over 5MB | 81,270 | 14,582ms |
Pages with more than 5MB of video have a median Speed Index of 14.6 seconds on mobile, versus 7.2 seconds for pages with no video at all. More video, slower page.
Why Speed Index, not LCP? Jump to heading
Look at that table again and you'll notice LCP is missing. That's deliberate. Across every video-weight bucket, median LCP stays roughly flat at about 4.2–5.1 seconds. A page with 50MB of video has about the same LCP as a page with 500KB.
This surprises people, so it's worth explaining. Two things are going on.
First, on most video pages the video isn't the LCP element at all. The heavy videos are usually below the fold; the LCP element is a hero image, a heading, or a poster image above it. Those elements are small and their paint time barely moves whether the page ships 500KB of off-screen video or 50MB, so median LCP stays flat while the page weight explodes.
Second, even when the video is the LCP element, file size isn't what LCP measures. LCP records when the largest element paints its first frame, not when its file finishes downloading. A video paints its first frame as soon as enough data arrives to decode one frame, and a 5MB video and a 50MB video reach that point at roughly the same time. The extra bytes keep arriving after the first frame is already on screen, so they never move LCP.
Speed Index is different. It measures how quickly the page visually fills in over time. A multi-megabyte video download hogs the network, starving the above-the-fold images, fonts, and CSS that the shopper is actually waiting on. Those competing resources arrive later, the page looks unfinished for longer, and Speed Index climbs.
So the win from lazy loading video is mostly a Speed Index win: defer the multi-megabyte downloads that aren't visible yet, and stop them from crowding out the resources that are. On the roughly 20% of video pages where the video is the LCP element, there is a second benefit. Deferring the below-the-fold videos frees up bandwidth so the above-the-fold LCP video can render its first frame sooner.
The real-user results at the top of this post are direct evidence of that mechanism working. The 78% drop in video bytes per page view is the multi-megabyte downloads that aren't visible yet no longer competing for the network.
How to use it Jump to heading
If you build themes with Liquid, you're likely already using video_tag. The fast path is the default path. Full details are in the video_tag filter reference on shopify.dev.
Default behavior (do nothing) Jump to heading
If you don't pass a loading attribute, video_tag automatically sets loading="lazy" for videos in sections further down the page, specifically sections at position 3 or later that aren't the header. To take advantage of it, just render your video normally:
{{ product.featured_media | video_tag }}
This mirrors how image_tag already works, and it reuses the same section-position logic. If you've read How layout position impacts three big web performance levers, this will feel familiar.
Override when you need to Jump to heading
The automatic behavior only kicks in when you don't specify loading. Any explicit value passes through verbatim and takes precedence, so you stay in control for the cases that matter:
{% comment %} Force eager for an above-the-fold hero video {% endcomment %}
{{ section.settings.video | video_tag: loading: 'eager', autoplay: true, muted: true }}
{% comment %} Force lazy explicitly {% endcomment %}
{{ product.featured_media | video_tag: loading: 'lazy' }}
If the default position-based rule doesn't fit your theme's layout, drive loading yourself with the section.index and section.location properties:
{%- liquid
if section.index > 2
assign loading = "lazy"
else
assign loading = "eager"
endif
-%}
{{ section.settings.video | video_tag: loading: loading }}
The rendered output is a <video> element carrying the attribute the browser needs:
<video loading="lazy" playsinline="playsinline" preload="metadata" aria-label="Potion beats" poster="//cdn.shopify.com/.../thumbnail.jpg">
<source src="//cdn.shopify.com/.../HD-1080p-7.2Mbps.mp4" type="video/mp4">
<img src="//cdn.shopify.com/.../thumbnail.jpg">
</video>
Gotchas Jump to heading
Lazy loading hurts performance if you apply it to the wrong element. The same rules that apply to images apply here.
Never lazy load a video above the fold. If a video is visible when the page loads, especially a hero video that's your LCP element, lazy loading adds a delay before it even starts downloading. That makes the page feel slower, the opposite of the goal. Leave loading off for above-the-fold videos (the automatic rule already avoids the header and the first sections), or set it to eager explicitly.
Autoplay still works. A lazy-loaded autoplay video triggers playback when it scrolls into view rather than on page load. You don't lose the autoplay effect; you just stop paying for it before anyone can see it.
It pairs with responsive posters. If you build custom video markup rather than relying on video_tag, native lazy loading slots right into the responsive <picture> + <video> poster technique from Fast video banners that work on every device: the poster shows the right image for each device while the below-the-fold video defers its download. That article called this combination "the future". Now it works natively.
Lazy videos stop blocking the window load event. Per the HTML spec, a lazy-loaded video no longer holds up the load event, so scripts and behavior gated on load fire sooner.
Browser support degrades gracefully. Native loading="lazy" on <video> is new. Chrome supports it as of version 150, and other browsers are catching up. Browsers that don't recognize the attribute ignore it and load the video eagerly, as they do now. There's no breakage and no fallback code to write, which is why the rollout was safe to ship for everyone at once.
Conclusion Jump to heading
Video is the heaviest asset on most storefronts that use it, and until now there was no native way to defer the off-screen ones. With native loading="lazy" on <video> and the automatic behavior in video_tag, below-the-fold videos defer their download by default. This improves Speed Index by keeping multi-megabyte files from crowding out the resources shoppers are waiting on.
If you develop Shopify themes, the recommendation is the same as it is for images: lean on the default video_tag behavior, and use the section.index property to override it only when your layout needs something different. Just don't lazy load anything above the fold.
- For the full filter reference, see the
video_tagdocs on shopify.dev. - For responsive video posters that pair with lazy loading, read Fast video banners that work on every device.
- To see how the same section-position logic works for images, read Lazy load images for performance and Announcing new Liquid features for better web performance.