And Image elements are the same , you can also delay loading video. Videos are usually loaded with elements (although there are problems) An alternative method , but the implementation is limited). However, how to delay loading depends on the use case. Let's discuss several scenarios, each of which requires a different solution.
For videos that do not play automatically #
For videos started by the user (that is, videos that do not play automatically), you may need to specify on the element preload attribute:
<video controls preload="none" poster="one-does-not-simply-placeholder.jpg"> <source src="one-does-not-simply.webm" type="video/webm"> <source src="one-does-not-simply.mp4" type="video/mp4"> </video>
The above example uses the attribute none with a preload value of to prevent the browser from preloading any video data. The poster attribute provides a placeholder for the element that will take up space when the video is loaded. The reason for this is that the default behavior for loading video varies from browser to browser:
- In Chrome, the default value of preload used to be auto, but starting with Chrome 64, it now defaults to metadata. Even so, on the desktop version of Chrome, part of the video may be preloaded with content range titles. Firefox, Edge, and Internet Explorer 11 behave similarly.
- Like the desktop version of Chrome, Safari 11.0 desktop version will preload a series of videos. Starting with version 11.2, only video metadata is preloaded. In Safari on iOS, videos are never preloaded.
- When Data protection mode Is activated, and preload defaults to none.
Because the browser's default behavior preload is not invariable, it may be your best choice to be clear. When the user starts playing, using preload="none" is the easiest way to delay loading video on all platforms. This preload attribute is not the only way to delay loading video content. Use video preload for fast playback It may give you some ideas and insights on how to handle video playback in JavaScript.
Unfortunately, when you want to use video instead of animated GIF, it doesn't prove useful, which will be introduced later.
For videos used as animated GIF substitutes #
Although animated gifs enjoy widespread use, they are lower than the equivalent video in many ways, especially in terms of file size. Animated gifs can be extended to a few megabytes of data. Videos with similar visual quality tend to be much smaller.
Using elements as an alternative to animated gifs is not as simple as elements. Animated gifs have three characteristics:
- They play automatically when loaded.
- They keep cycling( Although this is not always the case).
- They don't have tracks.
Implementing this with elements looks like this:
<video autoplay muted loop playsinline> <source src="one-does-not-simply.webm" type="video/webm"> <source src="one-does-not-simply.mp4" type="video/mp4"> </video>
The autoplay, muted, and loop properties of are self-evident. It is necessary for playinline to play automatically in iOS . Now you have a maintainable video that works across platforms as an alternative to GIF. But how to delay loading? First, modify your tags accordingly:
<video class="lazy" autoplay muted loop playsinline width="610" height="254" poster="one-does-not-simply.jpg"> <source data-src="one-does-not-simply.webm" type="video/webm"> <source data-src="one-does-not-simply.mp4" type="video/mp4"> </video>
You will notice that poster attribute , which allows you to specify a placeholder to occupy the space of the element until the video is delayed. And The delayed loading example is the same , store the video URL data Src in the attribute of each element. From there, use JavaScript code similar to the image delay loading example based on Intersection Observer:
document.addEventListener("DOMContentLoaded", function() { var lazyVideos = [].slice.call(document.querySelectorAll("video.lazy")); if ("IntersectionObserver" in window) { var lazyVideoObserver = new IntersectionObserver(function(entries, observer) { entries.forEach(function(video) { if (video.isIntersecting) { for (var source in video.target.children) { var videoSource = video.target.children[source]; if (typeof videoSource.tagName === "string" && videoSource.tagName === "SOURCE") { videoSource.src = videoSource.dataset.src; } } video.target.load(); video.target.classList.remove("lazy"); lazyVideoObserver.unobserve(video.target); } }); }); lazyVideos.forEach(function(lazyVideo) { lazyVideoObserver.observe(lazyVideo); }); } });
When you delay loading an element, you need to traverse all child elements and flip their data src attribute to src attribute. After completion, you need to trigger the loading of the video by calling the load method of the element, and then the media will automatically start playing according to the autoplay attribute.
Using this method, you have a video solution that simulates GIF animation behavior, but does not produce the same dense data usage as animated gifs, and you can delay loading the content.
Delay loading Library #
The following libraries can help you delay loading Videos:
- lozad.js Is a super lightweight option that uses only Intersection Observer. Therefore, it has high performance, but polyfill is required before it can be used on older browsers.
- yall.js Is a library that uses Intersection Observer and fallback to event handlers. It is compatible with IE11 and major browsers.
- If you need a React specific deferred load library, you can consider react-lazyload . Although it does not use Intersection Observer, it does provide a familiar method of delaying image loading for those who are used to developing applications using React.
Each of these deferred load libraries is well documented, providing a large number of markup patterns for your various deferred load efforts.