게시일: 2019년 8월 16일, 최종 업데이트: 2026년 7월 2일
이미지 요소와 마찬가지로 동영상을 지연 로드하는 것이 좋습니다. 동영상은 일반적으로 <video> 요소로 로드되지만 YouTube와 같은 다른 서비스에서 호스팅되는 동영상의 경우 <iframe>를 사용할 수 있습니다 (이 경우 지연 로드 iframe의 도움말 참고).
<video>를 지연 로드하는 방법은 사용 사례에 따라 다릅니다. 몇 가지 다른 솔루션이 있기 때문입니다.
loading 속성 사용
브라우저에서 미디어 요소 (<video> 및 <audio>)의 loading 속성을 지원하기 시작했습니다. 지원되는 경우 loading="lazy" 속성을 추가하기만 하면 미디어와 포스터 이미지가 모두 자동으로 지연 로드됩니다.
<video controls loading="lazy" 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>
loading="lazy"을 사용하면 표시 영역에 있거나 표시 영역 근처에 있을 때까지 poster 이미지가 전혀 로드되지 않으며, preload 속성을 사용하여 video을 얼마나 로드할지 결정합니다. 또한 autoplay 동영상은 표시 영역에 있거나 표시 영역 근처에 있을 때까지 자동재생되지 않습니다. loading="lazy" 속성은 poster, preload, autoplay 속성과 함께 작동하며 이러한 속성의 필요성을 대체하지는 않습니다.
미디어 요소에서 loading 속성을 지원하지 않는 브라우저는 이 속성을 무시하므로 poster 이미지가 즉시 로드되고 동영상은 다음에 설명할 preload 속성에 따라 로드됩니다.
preload 속성을 사용하여 자동 재생되지 않는 동영상을 지연 로드
동영상을 자동 재생하지 않는 것이 일반적으로 좋습니다. 이렇게 하면 사용자가 제어할 수 있기 때문입니다. 이 경우 <video> 요소에 preload 속성을 지정하는 것이 필요할 때까지 전체 동영상을 로드하지 않는 가장 좋은 방법입니다.
<video controls loading="lazy" 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>
이전 예에서는 none 값이 있는 preload 속성을 사용하여 브라우저가 뷰포트에 있더라도 모든 동영상 데이터를 미리 로드하지 못하도록 합니다. poster 속성은 동영상이 로드되는 동안 공간을 차지하는 자리표시자를 <video> 요소에 제공합니다.
대부분의 브라우저에서 preload은 기본적으로 metadata로 설정되며 동영상의 일부가 Content-Range 헤더를 사용하여 미리 로드됩니다. 이로 인해 원하는 것보다 더 많은 데이터가 다운로드될 수 있습니다. 브라우저는 메타데이터가 저장된 바이트를 알 수 없으며 파일 시작 부분에 저장되지 않을 수도 있습니다. 따라서 동영상 로드를 방지할 수 있는 가장 좋은 방법은 preload="none"를 사용하는 것입니다.
사용자가 onmouseenter 속성 (또는 이에 상응하는 mouseenter 이벤트 핸들러)으로 동영상을 마우스로 가져갈 때 메타데이터를 미리 로드하도록 추가로 개선할 수 있습니다.
<video controls
loading="lazy"
preload="none"
poster="one-does-not-simply-placeholder.jpg"
onmouseenter="event.target.setAttribute('preload','metadata')">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
이렇게 하면 사용자가 동영상을 재생할 때 지연이 줄어들 뿐만 아니라 동영상 재생을 시작하자마자 동영상 길이도 표시됩니다.
동영상은 LCP 후보가 될 수 있습니다. poster 이미지는 동영상보다 빠르게 로드되므로 LCP 후보인 경우 포스터 이미지를 사용해야 하지만 fetchpriority 속성 값이 "high"인 포스터 이미지로 미리 로드해야 합니다. 작성 시점에는 포스터 속성의 fetchpriority을 지정할 수 없기 때문입니다.
<link rel="preload" href="one-does-not-simply-placeholder.jpg" as="image" fetchpriority="high">
<video controls preload="none"
poster="one-does-not-simply-placeholder.jpg"
onmouseenter="event.target.setAttribute('preload','metadata')">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
LCP 요소인 동영상은 loading="lazy"를 사용해서는 안 됩니다. LCP 이미지를 지연 로드해서는 안 되는 것과 마찬가지입니다.
애니메이션 GIF 대체 역할을 하는 동영상
자동 재생 동영상은 GIF 스타일의 빠른 애니메이션에 일반적으로 사용됩니다. 애니메이션 GIF는 널리 사용되지만 파일 크기 등 여러 면에서 동영상에 비해 떨어집니다. 애니메이션 GIF는 데이터 범위가 수 메가바이트에 달할 수 있습니다. 시각적 품질이 비슷한 동영상은 훨씬 작은 경향이 있습니다.
<video> 요소를 애니메이션 GIF의 대체 요소로 사용하는 것은 <img> 요소만큼 간단하지 않습니다. 애니메이션 GIF에는 세 가지 특징이 있습니다.
- 로딩되면 자동으로 재생됩니다.
- 연속으로 반복됩니다 (항상 그런 것은 아님).
- 오디오 트랙이 없습니다.
<video> 요소를 사용하여 이를 달성하면 다음과 같습니다.
<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>
loading="lazy" 속성은 동영상이 표시 영역에 가까워질 때까지 로드하지 않습니다. autoplay, muted, loop 속성은 설명이 필요하지 않습니다. iOS에서 자동 재생이 발생하려면 playsinline가 필요합니다.
이제 플랫폼 간에 작동하는 서비스 가능한 동영상-GIF 대체가 있습니다. 하지만 어떻게 지연 로드해야 할까요?
이를 지원하는 브라우저의 경우 loading="lazy"가 가장 쉬운 옵션입니다.
<video loading="lazy" 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>
다른 브라우저에서 동영상의 지연 로딩을 지원하려면 JavaScript를 사용하고 <video> 마크업을 적절하게 수정해야 합니다.
<video class="lazy" preload="none" controls muted loop playsinline width="610" height="254" poster="one-does-not-simply.jpg">
<source src="one-does-not-simply.webm" type="video/webm">
<source src="one-does-not-simply.mp4" type="video/mp4">
</video>
autoplay가 삭제되고 class="lazy", preload="none", poster 속성이 추가된 것을 확인할 수 있습니다. 이러한 속성을 사용하면 동영상이 지연 로드될 때까지 <video> 요소의 공간을 차지할 자리표시자를 지정할 수 있습니다. 그런 다음 JavaScript 교차 관찰자를 사용하여 자동 재생을 다시 사용 설정합니다.
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) {
video.target.removeAttribute('preload');
video.target.removeAttribute('controls');
video.target.autoplay = true;
video.target.classList.remove("lazy");
lazyVideoObserver.unobserve(video.target);
}
});
});
lazyVideos.forEach(function(lazyVideo) {
lazyVideoObserver.observe(lazyVideo);
});
}
});
이 방법을 사용하면 동영상이 기본적으로 자동재생되지 않으며 교차 관찰자가 동영상이 표시 영역에 들어가는 것으로 감지할 때만 자동재생됩니다. 또한 controls 속성은 JavaScript가 실패하는 경우를 처리합니다. 따라서 애니메이션 GIF 동작을 에뮬레이션하지만 애니메이션 GIF와 동일한 집약적인 데이터 사용량을 발생시키지 않는 동영상 솔루션을 사용할 수 있으며 콘텐츠를 지연 로드할 수 있습니다.
지연 로드 라이브러리
다음 라이브러리를 사용하면 동영상을 지연 로드할 수 있습니다.
- vanilla-lazyload 및 lozad.js는 Intersection Observer만 사용하는 매우 가벼운 옵션입니다. 따라서 성능이 매우 뛰어나지만 이전 브라우저에서 사용하려면 폴리필해야 합니다.
- React 전용 지연 로딩 라이브러리가 필요한 경우 react-lazyload를 고려해 보세요. Intersection Observer를 사용하지는 않지만 React로 애플리케이션을 개발하는 데 익숙한 사용자를 위해 이미지 지연 로딩의 친숙한 방법을 제공합니다.
이러한 지연 로딩 라이브러리는 각각 다양한 지연 로딩 작업을 위한 마크업 패턴이 풍부하게 포함된 문서가 잘 작성되어 있습니다.
<video>의 loading 속성이 더 많은 브라우저에서 지원됨에 따라 더 많은 제어를 원하는 경우를 제외하고 JavaScript 솔루션 (라이브러리 포함)이 기본 제공 솔루션보다 덜 사용될 것으로 예상됩니다.