Search code examples
javascripthtmlvideolazy-loading

How can I replace a video with a placeholder image so that the video loads after the DOM?


Consider this website that consists of a hero video on top and some content below.

<body class="d-flex static_pages-index flex-column">
  <div class="w-100 flex-shrink-0">
    <header>
      <video autoplay="" loop="" muted="" playsinline="" poster="my_hero.mp4">
        <source src="my_hero.mp4" type="video/mp4">
      </video>
      <nav class="navbar navbar-expand-lg pb-2 navbar-dark">
      </nav>
    </header>
    <div class="container-fluid">
      <div id="promo"></div>
    </div>
  </div>
  <footer class="footer mt-auto pb-5 pt-4 bg-dark">
    <div class="container">
    </div>
  </footer>
</body>

If the hero video is large (even a few MB), this will delay the page load and reduce the user experience.

I have read that it's possible to use a poster attribute to specify a placeholder image while the video loads, which sounds great, but I don't know how to implement this.

How can I implement this so that the page loads with the placeholder image, and then the video is loaded in after?


Solution

  • You are right to note that if you are asking the browser to make the poster image itself, i.e. asking it to extract a single frame from the MP4 after downloading the MP4, that won't be useful. But you can help it:

    In the poster attribute, specify a static image, not the movie itself

    For example, take a single frame of the MP4, save it as a low-resolution single-frame JPEG, e.g. my_hero.jpg. Then the poster attribute will download just that image.

    When saving the JPEG, you can use strong compression to make it very low resolution indeed, perhaps only a couple of kilobytes. It only needs to give a very rough idea of what will be present on the video frame, to have the desired effect.

    <body class="d-flex static_pages-index flex-column">
      <div class="w-100 flex-shrink-0">
        <header>
          <video autoplay="" loop="" muted="" playsinline="" poster="my_hero.jpg">
            <source src="my_hero.mp4" type="video/mp4">
          </video>
          <nav class="navbar navbar-expand-lg pb-2 navbar-dark">
          </nav>
        </header>
        <div class="container-fluid">
          <div id="promo"></div>
        </div>
      </div>
      <footer class="footer mt-auto pb-5 pt-4 bg-dark">
        <div class="container">
        </div>
      </footer>
    </body>