Home / The Cut / Website video above the fold without killing page speed: how we ship motion that still scores
Web Performance

Website video above the fold without killing page speed: how we ship motion that still scores

Motion sells. A 40 MB autoplay loop does not. This is the pattern running on our own homepage.

We are a video studio. Of course we want motion above the fold. A hero that moves does the thing a headline cannot: it proves the brand has a pulse before a word is read. Done carelessly, it also hands you a Largest Contentful Paint of six seconds, a red PageSpeed score and a homepage that stutters on the phones your customers actually own.

Both things are true, so we built a pattern that keeps the motion and keeps the score. It is what runs on the Narsaik homepage and across our portfolio, and it is what we hand to every developer who asks how a video studio's site loads this fast. Nothing here is exotic. It is a short list of decisions made in the right order.

Rule one: the poster is your LCP, not the video

Lighthouse measures Largest Contentful Paint on the biggest element visible when it paints. For a hero video that element is the poster frame, not the stream. Browsers count the poster image (or the first decoded frame if there is no poster) as the LCP candidate, so the fastest possible hero is one where a well-compressed poster paints immediately and the video quietly takes over a moment later.

Practically:

  • Export the poster as a real image. WebP or AVIF at the hero's rendered width, usually 1600 to 1920 px, landing around 80 to 150 KB.
  • Pick a frame from the clip itself so the swap from still to motion is invisible.
  • Preload it in the head: <link rel="preload" as="image" href="/hero-poster.webp" fetchpriority="high">. It should be the first image request on the page.
  • Set explicit width and height on the video element, or an aspect-ratio in CSS, so nothing shifts when the poster arrives.

Get the poster right and you have already won most of the argument. Everything below is about not losing it again.

Rule two: do not let the browser preload the video

The default preload behaviour on a video element is browser-dependent and often behaves like auto, which means the browser may start pulling the whole file during the critical loading window, competing with your fonts and CSS. Set it yourself, every time.

  • preload="none" for any video below the fold or behind a play button. Nothing downloads until it is asked for.
  • preload="metadata" for a hero that autoplays. The browser fetches the header and the first frames, then starts streaming once autoplay fires.

For an autoplaying hero, metadata is the right call. The poster covers the gap and, because the file is small (next section), the stream is running before anyone notices the still.

The tag pattern

This is the hero video markup we ship, give or take a class name:

<video
  class="hero-video"
  autoplay muted loop playsinline
  preload="metadata"
  poster="/hero-poster.webp"
  width="1920" height="1080"
  aria-hidden="true">
  <source src="/hero-720.mp4" type="video/mp4">
</video>

Each attribute is doing a job. autoplay muted playsinline is the only combination that mobile Safari and Chrome will autoplay without a tap; drop muted and the video will not start. loop because a hero clip is ambient, not narrative. aria-hidden because a decorative loop should not be announced to screen readers; the headline beside it carries the meaning. If the clip does carry meaning, give it controls and a transcript instead of hiding it.

We do not add a WebM source for hero loops. At these file sizes the savings are small and the second encode is one more thing to break. H.264 in an MP4 container plays everywhere.

Encode for the web, not the screening room

The file your editor exports is not the file that goes on the site. Our targets for a hero loop:

  • 8 to 15 seconds. Longer loops are bigger and nobody watches a hero for 20 seconds.
  • 1280 by 720. Scaled and cropped behind text, 720p is visually indistinguishable from 1080p and roughly half the bytes.
  • H.264, CRF 28 to 30, slow preset. Aim for under 3 MB. Under 2 MB is better.
  • No audio track. It is muted anyway and it costs bytes. Strip it with -an.
  • faststart. Moves the index to the front of the file so playback begins before the download finishes. In ffmpeg that is -movflags +faststart.
  • 24 or 30 fps. Do not ship 60.

Content matters as much as settings. A dark, slow-moving shot looks perfect at CRF 30. Fast cuts, confetti and water spray need a lower CRF and will blow the budget. If the clip will not compress, pick a different clip. On a shoot day we plan the hero loop as its own line on the derivative map for exactly this reason: a slow push on a product or a steady wide of the space, shot to loop.

Below the fold, load nothing until it is needed

Portfolio grids and case-study pages often carry several videos. Loading them all on page load is how a 90 becomes a 55. Give each below-fold video preload="none", a poster, and a data-src instead of src. Then let an IntersectionObserver attach the source and play when the element is close to the viewport, and pause it when it leaves:

const io = new IntersectionObserver((entries) => {
  entries.forEach(({ isIntersecting, target }) => {
    if (isIntersecting) {
      if (!target.src) { target.src = target.dataset.src; target.load(); }
      target.play().catch(() => {});
    } else if (!target.paused) {
      target.pause();
    }
  });
}, { rootMargin: '200px 0px' });

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

The 200 px margin starts the fetch just before the video scrolls into view, so it is playing by the time the user sees it. Pausing offscreen videos matters as much as the lazy load. A phone decoding four loops at once gets warm, drops frames and scrolls badly, and none of that shows up in Lighthouse; it shows up in the bounce rate.

Respect prefers-reduced-motion

Some users have asked their operating system to reduce motion. Honour it. Show the poster and never start the video.

  • CSS: inside @media (prefers-reduced-motion: reduce), hide the video element and let the wrapper show the poster as a background.
  • JS: check window.matchMedia('(prefers-reduced-motion: reduce)').matches before calling play(), and skip attaching the source at all.

The JS route also saves the bytes. We do both.

One autoplaying video at a time

The most common performance failure we see on agency and studio sites is not one big file. It is five medium files all autoplaying in the first viewport: a hero, three service cards with loops and a logo ticker. Each one is fine. Together they are 12 MB and four decoders running on a phone.

Rule of thumb: one autoplaying video in the initial viewport. Everything else waits for the observer, a hover or a tap. If a section needs to feel alive without video, a well-timed CSS transition or a short animated WebP does the job at a fraction of the cost.

A hero video that costs two seconds of LCP is not a brand statement. It is a bounce.

Measure it before you argue about it

Run PageSpeed Insights on the mobile tab, not desktop. Mobile is where the field data comes from and where the budget is tight. Look at three things:

  1. The LCP element. It should be the poster image or the headline. If the report names the video, the poster is missing or arriving late.
  2. Bytes transferred at load. With the pattern above, a hero page should land well under 1.5 MB before any interaction, video included.
  3. Main-thread work. Video decoding happens off the main thread, but a JavaScript player library wrapping the video does not. Native <video> needs no library.

Then look at the field data, the Core Web Vitals from real Chrome users, after 28 days. Lab scores are a guess; field data is the grade. Our homepage and portfolio run this exact pattern, so if you want to see it in the wild, open them on your phone and run them through PageSpeed. If the site is part of a larger build, the rest of the checklist lives in our small business website checklist.

When to use a static image instead

Sometimes the right answer is a still. Use a photo instead of video when:

  • The clip was not shot for a loop. A cut from a narrative film rarely loops cleanly and reads as a glitch.
  • The page's job is fast conversion. A landing page for paid traffic is measured in cost per lead, and every hundred milliseconds counts. Growth Boss runs those pages for our clients; we give them stills up top and a single click-to-play video lower down.
  • Field LCP on mobile is already over 2.5 seconds for reasons you cannot fix this sprint. Fix the score first, then earn the motion back.
  • The audience is on slow connections or metered data, where a 3 MB loop is a real cost to them.

Motion is a feature, not a default. It earns its place when the clip was built for it, the file is disciplined and the poster does the first job. Do that and you get the thing everyone says you cannot have: a cinematic hero and a green score.

FAQ

Does a background video hurt page speed?

Only when it is loaded carelessly. A hero video with a preloaded poster, preload set to metadata, and a file under 3 MB has almost no effect on Largest Contentful Paint, because the poster image is what gets measured. Large files, preload set to auto, or several autoplaying videos at once are what hurt.

What is the best video format for a website hero?

H.264 in an MP4 container, encoded at 1280 by 720 with CRF 28 to 30, the audio track removed and the faststart flag set. It plays natively in every browser and, at 8 to 15 seconds, lands well under 3 MB.

Should hero video use preload none or preload metadata?

Use preload metadata for a hero that autoplays so playback starts quickly once the poster has painted. Use preload none for any video below the fold or behind a play button, and attach the source with an IntersectionObserver when it is needed.

Does autoplay video count as the Largest Contentful Paint?

The poster image, or the first frame if there is no poster, is what gets measured as the LCP candidate for a hero video. That is why the poster should be a small, properly sized WebP or AVIF that is preloaded in the head.

Related notes

Want this done for you?

Narsaik handles the creative — video, brand, web. When you need the full growth engine behind it (paid media, CRM, SEO at scale), we work hand-in-hand with our growth marketing partner Growth Boss.

Start a Project

See the work