DEV Community

BanjaminHan
BanjaminHan

Posted on

Your Website's Video Is Probably Killing Your LCP. Here's a Checklist

A full-width hero video looks great in the design file. In production, it's often the heaviest thing on the page, and it quietly drags down your performance score.
This is a checklist I use whenever video shows up in a frontend project. Each item is small, but together they make a big difference.
First, measure
Before changing anything, find out whether video is actually your problem:

  1. Run Lighthouse or PageSpeed Insights on the page.
  2. In Chrome DevTools, open the Network tab, filter by Media, and sort by size.
  3. In the Performance panel, check what element is reported as your LCP. If your LCP element is a video poster or a frame, or if the video request competes with your critical resources on a slow connection, keep reading. The checklist
  4. Compress the source file first Most videos exported from editors or screen recorders are far heavier than they need to be. A sensible web-friendly baseline with FFmpeg: ffmpeg -i input.mp4 \ -c:v libx264 -crf 26 -preset slow -pix_fmt yuv420p \ -c:a aac -b:a 96k \ -movflags +faststart \ output.mp4

If you'd rather not touch the command line, an online tool such as VideoBee's video compressor does the same job in the browser. (Disclosure: I work on VideoBee.)

  1. Use the right resolution A background video behind a headline rarely needs 4K. Match the video to how it's displayed: ffmpeg -i input.mp4 -vf "scale=-2:720,fps=30" -c:v libx264 -crf 26 -an hero-720.mp4

For decorative background video, 720p (or even lower) is often enough.

  1. Drop the audio track when it's not used Muted autoplay backgrounds don't need audio at all. -an removes it and saves bytes.
  2. Keep it short

A 6 to 10 second loop is usually all a hero needs. If you have a longer source, trim it. A browser-based video cutter is handy for quick trims, or use FFmpeg:
ffmpeg -ss 00:00:03 -to 00:00:11 -i input.mp4 -c:v libx264 -crf 26 -an loop.mp4

  1. Provide modern formats with a fallback WebM (VP9) and AV1 can be smaller than H.264 at similar quality. Offer them first and keep MP4 as the universal fallback:

Create the WebM version:
ffmpeg -i hero.mp4 -c:v libvpx-vp9 -crf 33 -b:v 0 -an hero.webm

Need to convert between formats without installing anything? A video converter works for one-off jobs.
Browsers pick the first  they can play, so order matters: most efficient format first, safest format last.

  1. Always set a poster image The poster shows immediately while the video loads, so users never see an empty box. Generate one from a frame: ffmpeg -i hero.mp4 -frames:v 1 -q:v 3 hero-poster.jpg

Optimize the poster too (modern formats like WebP or AVIF work), because in many cases it becomes the element that determines your LCP.

  1. Control preloading The preload attribute tells the browser how aggressively to fetch the video: ● preload="none": don't download anything until the user interacts (good for below-the-fold videos). ● preload="metadata": fetch only duration and dimensions. ● preload="auto": let the browser decide (can be expensive on mobile). For non-critical videos, none or metadata is usually the right call.
  2. Lazy-load videos below the fold Don't load videos the user hasn't scrolled to. A small IntersectionObserver does the job:

const observer = new IntersectionObserver((entries, obs) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
const video = entry.target;
video.src = video.dataset.src;
video.load();
video.play().catch(() => {});
obs.unobserve(video);
});
});

document.querySelectorAll("video[data-src]").forEach((v) => observer.observe(v));

  1. Make sure the server supports range requests and caching Browsers fetch video in chunks using HTTP range requests. Check that your server or CDN returns Accept-Ranges: bytesand sets sensible Cache-Control headers for video files. Putting videos behind a CDN also helps users far from your origin.
  2. Use +faststart for MP4 Moving the MP4 metadata (the moov atom) to the beginning of the file lets playback start before the entire file is downloaded. It's a single flag: -movflags +faststart.
  3. Consider not autoplaying at all For longer product demos, a poster with a play button (and the video loaded on click) is much lighter than an autoplaying video. Reserve autoplay for short, muted loops.
  4. Respect user preferences Some users ask their OS to reduce motion or save data. You can honor that: @media (prefers-reduced-motion: reduce) { .hero-video { display: none; } }

Show the poster image instead.
Before and after
Measure the same page before and after applying the checklist, and record:
Metric
Before
After
Video file size
measure
measure
LCP
measure
measure
Total page weight
measure
measure
[Add your own numbers and a Lighthouse screenshot here. Real before/after data is far more convincing than generic claims.]
The short version (save this)
● [ ] Compress the source (CRF 24 to 28 for web)
● [ ] Reduce resolution and frame rate to what the layout needs
● [ ] Remove audio if the video is muted
● [ ] Trim to the shortest useful loop
● [ ] Offer WebM/AV1 plus an MP4 fallback
● [ ] Set an optimized poster
● [ ] Use preload="none" or "metadata" where possible
● [ ] Lazy-load below-the-fold videos
● [ ] Enable range requests, caching, and a CDN
● [ ] Add -movflags +faststart to MP4s
● [ ] Don't autoplay long videos
● [ ] Respect prefers-reduced-motion
What's the worst video-related performance problem you've found in the wild? Tell me in the comments.

Top comments (0)