user186141
user186141

Reputation: 63

Lazy Load html video with jQuery

I am trying to lazy load my html video. It's in my WordPress template and I want for video to load when user get to its viewpoint.

I am new in JS so I think something is wrong. How can I test if lazy loading is working correctly? Maybe my function is not valid?

<video id="myVideo" autoplay loop muted playsinline src="<?= VIDEO ?>/video_footer.mp4">
    <source data-src="<?= VIDEO ?>/video_footer.mp4" type="video/mp4">
</video>

js:

$(function() {
$("video.myVideo source").each(function() {
    var sourceFile = $(this).attr('data-src');
    $(this).attr("src", sourceFile);
    var video = this.parentElement;
    video.load();
    video.play();
  });
});

Upvotes: 3

Views: 2984

Answers (1)

kaize
kaize

Reputation: 811

It's unlikely that is working as it is.

You have already set the source to video so even if the function is working, the video file is already there, so no lazy load...

This is the correct setup:

<video id="myVideo" autoplay loop muted playsinline src="">
    <source data-src="<?= VIDEO ?>/video_footer.mp4" type="video/mp4">
</video>

Then you can check if you function works


Another solution is to use intersection observer and do it with pure JavaScript, simple, lightweight and works in most cases

Lazy load video with pure JavaScript:

<script type="text/javascript">
const lazyvideo = document.querySelectorAll('.lazy-video');
observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.intersectionRatio > 0) {
      console.log('video in the view');
         if (entry.target.querySelector('source').getAttribute('data-src') !== null) {
          const source = entry.target.querySelector('source').getAttribute('data-src')
          entry.target.setAttribute('src', source);
        }
      observer.unobserve(entry.target);
    } else {
      console.log('video out of view');
    }
  });
});

lazyvideo.forEach(video => {
  observer.observe(video);
});
</script>

I have added console.log('video out of view'); & console.log('video in the view'); in order to check the console whether the video is in view or not.

With this script if you want a video to be lazy loaded, just add a class lazy-video to it and you are all set ;)

Full code:

const lazyvideo = document.querySelectorAll('.lazy-video');
observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.intersectionRatio > 0) {
      console.log('video in the view');
         if (entry.target.querySelector('source').getAttribute('data-src') !== null) {
          const source = entry.target.querySelector('source').getAttribute('data-src')
          entry.target.setAttribute('src', source);
        }
      observer.unobserve(entry.target);
    } else {
      console.log('video out of view');
    }
  });
});

lazyvideo.forEach(video => {
  observer.observe(video);
});
#myVideo {
  max-width:400px;
  width:100%;
}
<video id="myVideo" class="lazy-video" autoplay loop muted playsinline src="">
    <source data-src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4">
</video>

If you want to be sure that lazy load works

  • Open you Chrome developer tools and go to Network and select the media tab
  • While you have the tools open reload the page
  • If you haven't scroll to the video section then you should not see the video in your console
  • While you scroll when you are in the view of the video section then you must see the video loading on the media tab

See screenshots below:

Not there yet:

enter image description here

In view:

enter image description here

Upvotes: 3

Related Questions