이미지와 <iframe>
요소는 다른 유형의 리소스보다 대역폭을 더 많이 사용하는 경우가 많습니다. <iframe>
요소의 경우 내부 페이지를 로드하고 렌더링하는 데 상당한 추가 처리 시간이 소요될 수 있습니다.
이미지 지연 로드의 경우 초기 표시 영역 외부에 있는 이미지의 로드를 지연하면 초기 표시 영역 내의 더 중요한 리소스에 대한 대역폭 경합을 줄이는 데 도움이 될 수 있습니다. 이렇게 하면 네트워크 연결이 좋지 않은 경우에 페이지의 최대 콘텐츠 렌더링 시간 (LCP)이 개선될 수 있으며, 재할당된 대역폭은 LCP 후보가 더 빠르게 로드되고 렌더링되는 데 도움이 될 수 있습니다.
<iframe>
요소의 경우 시작 중에 지연 로드하여 페이지의 다음 페인트에 대한 상호작용(INP)을 개선할 수 있습니다. 이는 <iframe>
가 자체 하위 리소스가 있는 완전히 별개의 HTML 문서이기 때문입니다.
<iframe>
요소는 별도의 프로세스에서 실행할 수 있지만 다른 스레드와 프로세스를 공유하는 경우가 많습니다. 이로 인해 페이지가 사용자 입력에 덜 반응하는 상황이 발생할 수 있습니다.
따라서 화면 밖 이미지와 <iframe>
요소의 로드를 지연하는 것은 추구할 가치가 있는 기법이며 성능 측면에서 상당히 좋은 결과를 얻기 위해 상당히 적은 노력이 필요합니다. 이 모듈에서는 페이지의 중요한 시작 기간 동안 더 빠르고 나은 사용자 환경을 위해 이러한 두 가지 유형의 요소를 지연 로드하는 방법을 설명합니다.
loading
속성으로 이미지 지연 로드
<img>
요소에 loading
속성을 추가하여 브라우저에 로드 방법을 알릴 수 있습니다.
"eager"
는 이미지가 초기 뷰포트 밖에 있더라도 즉시 로드되어야 한다고 브라우저에 알립니다. 이는loading
속성의 기본값이기도 합니다."lazy"
는 이미지가 표시된 표시 영역에서 설정된 거리 내에 있을 때까지 이미지 로드를 지연시킵니다. 이 거리는 브라우저마다 다르지만 사용자가 이미지로 스크롤할 때 이미지가 로드될 만큼 충분히 넓게 설정되는 경우가 많습니다.
또한 <picture>
요소를 사용하는 경우 loading
속성은 <picture>
요소 자체가 아닌 하위 <img>
요소에 적용해야 합니다. 이는 <picture>
요소가 다양한 이미지 후보를 가리키는 추가 <source>
요소를 포함하는 컨테이너이고 브라우저가 선택한 후보가 하위 <img>
요소에 직접 적용되기 때문입니다.
초기 표시 영역에 있는 이미지를 지연 로드하지 않음
초기 표시 영역 외부에 배치된 <img>
요소에만 loading="lazy"
속성을 추가해야 합니다. 그러나 페이지가 렌더링되기 전에 뷰포트 내에서 요소의 정확한 상대 위치를 알기는 복잡할 수 있습니다. 다양한 표시 영역 크기, 가로세로 비율, 기기를 고려해야 합니다.
예를 들어 데스크톱 표시 영역은 더 많은 세로 공간을 렌더링하므로 휴대전화의 표시 영역과는 상당히 다를 수 있습니다. 따라서 물리적으로 더 작은 기기의 초기 표시 영역에 표시되지 않는 이미지를 초기 표시 영역에 맞출 수 있습니다. 세로 모드 방향으로 사용되는 태블릿도 상당한 양의 세로 공간을 표시하며, 경우에 따라 일부 데스크톱 기기보다 더 많은 공간을 표시할 수도 있습니다.
하지만 loading="lazy"
적용을 피해야 하는 경우가 분명히 있습니다. 예를 들어 히어로 이미지의 경우 또는 <img>
요소가 접힌 부분 위에 표시되거나 모든 기기의 레이아웃 상단 근처에 표시될 가능성이 있는 다른 이미지 사용 사례에서는 <img>
요소에서 loading="lazy"
속성을 생략해야 합니다. LCP 후보가 될 가능성이 높은 이미지의 경우 더욱 중요합니다.
지연 로드되는 이미지는 브라우저가 레이아웃을 완료할 때까지 기다려야 이미지의 최종 위치가 뷰포트 내에 있는지 알 수 있습니다. 즉, 표시되는 표시 영역의 <img>
요소에 loading="lazy"
속성이 있는 경우 원시 마크업에서 미리 로드 스캐너에 의해 발견되는 즉시 가져오는 대신 모든 CSS가 다운로드, 파싱, 페이지에 적용된 후에 요청됩니다.
<img>
요소의 loading
속성은 모든 주요 브라우저에서 지원되므로 JavaScript를 사용하여 이미지를 지연 로드할 필요가 없습니다. 브라우저에서 이미 제공하는 기능을 제공하기 위해 페이지에 추가 JavaScript를 추가하면 INP와 같은 페이지 성능의 다른 측면에 영향을 미치기 때문입니다.
이미지 지연 로드 데모
<iframe>
요소 지연 로드
<iframe>
요소가 뷰포트에 표시될 때까지 지연 로드하면 상당한 데이터를 절약하고 최상위 페이지를 로드하는 데 필요한 중요한 리소스의 로드를 개선할 수 있습니다. 또한 <iframe>
요소는 기본적으로 최상위 문서 내에 로드된 전체 HTML 문서이므로 상당수의 하위 리소스(특히 JavaScript)를 포함할 수 있습니다. 이러한 프레임 내 태스크에 상당한 처리 시간이 필요한 경우 페이지의 INP에 상당한 영향을 미칠 수 있습니다.
서드 파티 삽입은 <iframe>
요소의 일반적인 사용 사례입니다. 예를 들어 삽입된 동영상 플레이어 또는 소셜 미디어 게시물은 일반적으로 <iframe>
요소를 사용하며, 대규모 하위 리소스가 필요한 경우가 많습니다. 이로 인해 최상위 페이지 리소스의 대역폭 경합이 발생할 수도 있습니다. 예를 들어 YouTube 동영상 삽입을 지연 로드하면 초기 페이지 로드 중에 500KiB가 넘게 절약되지만 Facebook 좋아요 버튼 플러그인을 지연 로드하면 200KiB가 넘게 절약됩니다. 이 중 대부분은 JavaScript입니다.
어느 쪽이든 페이지의 스크롤 아래에 <iframe>
가 있을 때는 미리 로드하는 것이 중요하지 않은 경우 지연 로드하는 것이 좋습니다. 이렇게 하면 사용자 환경을 크게 개선할 수 있기 때문입니다.
<iframe>
요소의 loading
속성
<iframe>
요소의 loading
속성도 모든 주요 브라우저에서 지원됩니다. loading
속성의 값과 동작은 loading
속성을 사용하는 <img>
요소와 동일합니다.
"eager"
가 기본값입니다. 브라우저에<iframe>
요소의 HTML과 하위 리소스를 즉시 로드하도록 알립니다."lazy"
는<iframe>
요소의 HTML 및 하위 리소스를 표시 영역에서 사전 정의된 거리 내에 있을 때까지 로드하지 않습니다.
iframe 지연 로드 데모
건물 외관
페이지 로드 중에 삽입된 콘텐츠를 즉시 로드하는 대신 사용자 상호작용에 따라 필요할 때 로드할 수 있습니다. 이는 사용자가 상호작용할 때까지 이미지 또는 다른 적절한 HTML 요소를 표시하여 수행할 수 있습니다. 사용자가 요소와 상호작용하면 서드 파티 삽입으로 대체할 수 있습니다. 이 기법을 파사드라고 합니다.
파사드의 일반적인 사용 사례는 서드 파티 서비스의 동영상 삽입입니다. 삽입 시 동영상 콘텐츠 자체 외에도 JavaScript와 같이 비용이 많이 들 수 있는 많은 하위 리소스를 추가로 로드해야 할 수 있습니다. 이 경우 동영상을 자동재생해야 할 타당한 이유가 없는 한 동영상 삽입은 사용자가 재생 버튼을 클릭하여 재생하기 전에 상호작용해야 합니다.
이때 동영상 삽입과 시각적으로 유사한 정적 이미지를 표시하고 그 과정에서 상당한 대역폭을 절약할 수 있습니다. 사용자가 이미지를 클릭하면 실제 <iframe>
삽입으로 대체되며, 이로 인해 서드 파티 <iframe>
요소의 HTML과 하위 리소스가 트리거되어 다운로드가 시작됩니다.
초기 페이지 로드를 개선하는 것 외에도 사용자가 동영상을 재생하지 않으면 동영상을 전송하는 데 필요한 리소스가 다운로드되지 않는다는 또 다른 이점이 있습니다. 이는 사용자가 자신의 요구사항에 대해 잘못된 가정을 하지 않고 실제로 원하는 항목만 다운로드할 수 있도록 하므로 좋은 패턴입니다.
채팅 위젯은 또 다른 훌륭한 노출 영역 기법 사용 사례입니다. 대부분의 채팅 위젯은 페이지 로드와 사용자 입력에 대한 응답성에 부정적인 영향을 줄 수 있는 상당한 양의 JavaScript를 다운로드합니다. 미리 로드하는 것과 마찬가지로 비용은 로드 시 발생하지만 채팅 위젯의 경우 모든 사용자가 상호작용하려는 것은 아닙니다.
반면에 파사드를 사용하면 서드 파티 '채팅 시작' 버튼을 가짜 버튼으로 대체할 수 있습니다. 사용자가 포인터를 적절한 시간 동안 위로 가져가거나 클릭하는 등 의미 있는 상호작용을 하면 사용자가 필요할 때 실제 작동하는 채팅 위젯이 자리를 잡습니다.
자체 파사드를 빌드할 수도 있지만 YouTube 동영상의 경우 lite-youtube-embed
, Vimeo 동영상의 경우 lite-vimeo-embed
, 채팅 위젯의 경우 React Live Chat Loader와 같이 더 인기 있는 서드 파티에서 사용할 수 있는 오픈소스 옵션이 있습니다.
JavaScript 지연 로드 라이브러리
<video>
요소, <video>
요소 poster
이미지, CSS background-image
속성으로 로드된 이미지 또는 기타 지원되지 않는 요소를 지연 로드해야 하는 경우 이러한 유형의 리소스 지연 로드는 브라우저 수준 기능이 아니므로 lazysizes 또는 yall.js와 같은 JavaScript 기반 지연 로드 솔루션을 사용하여 지연 로드할 수 있습니다.
특히 오디오 트랙 없이 <video>
요소를 자동재생 및 반복하는 것은 애니메이션 GIF를 사용하는 것보다 훨씬 효율적인 대안입니다. 애니메이션 GIF는 동등한 시각적 품질의 동영상 리소스보다 크기가 몇 배나 클 수 있습니다. 그렇더라도 이러한 동영상은 대역폭 측면에서 여전히 상당할 수 있으므로 지연 로드는 낭비되는 대역폭을 줄이는 데 큰 도움이 되는 추가 최적화입니다.
이러한 라이브러리의 대부분은 Intersection Observer API를 사용하여 작동하며, 페이지의 HTML이 초기 로드 후 변경되는 경우 Mutation Observer API도 사용하여 요소가 사용자의 뷰포트에 들어오는 시점을 인식합니다. 이미지가 표시되거나 뷰포트에 접근하면 JavaScript 라이브러리는 비표준 속성(일반적으로 data-src
또는 유사한 속성)을 올바른 속성(예: src
)으로 대체합니다.
애니메이션 GIF를 대체하는 동영상이 있지만 JavaScript 솔루션으로 지연 로드하려고 한다고 가정해 보겠습니다. 이는 다음과 같은 마크업 패턴을 사용하여 yall.js로 가능합니다.
<!-- The autoplay, loop, muted, and playsinline attributes are to
ensure the video can autoplay without user intervention. -->
<video class="lazy" autoplay loop muted playsinline width="320" height="480">
<source data-src="video.webm" type="video/webm">
<source data-src="video.mp4" type="video/mp4">
</video>
기본적으로 yall.js는 "lazy"
클래스가 있는 모든 요건을 충족하는 HTML 요소를 관찰합니다. yall.js가 페이지에서 로드되고 실행되면 사용자가 동영상을 표시 영역으로 스크롤할 때까지 동영상이 로드되지 않습니다. 이때 <video>
요소의 하위 <source>
요소에 있는 data-src
속성이 src
속성으로 전환되어 동영상을 다운로드하고 자동으로 재생을 시작하는 요청을 전송합니다.
학습한 내용 테스트
<img>
및 <iframe>
요소 모두의 loading
속성의 기본값은 무엇인가요?
"eager"
"lazy"
JavaScript 기반 지연 로드 솔루션을 사용하는 것이 적절한 경우는 언제인가요?
<video>
요소의 포스터 이미지를 지연 로드하기 위한 자동 재생 동영상의 경우와 같이 loading
속성이 지원되지 않는 리소스의 경우
파사드는 언제 유용한 기법인가요?
다음 단계: 미리 가져오기 및 사전 렌더링
이제 이미지 및 <iframe>
요소의 지연 로드를 처리할 수 있으므로 사용자의 요구사항을 충족하면서 페이지를 더 빠르게 로드할 수 있습니다. 하지만 리소스를 미리 로드하는 것이 바람직한 경우도 있습니다. 다음 모듈에서는 미리 가져오기 및 사전 렌더링에 대해 알아보고, 이러한 기법을 신중하게 사용하면 후속 페이지를 미리 로드하여 후속 페이지로의 탐색 속도를 크게 높일 수 있는 방법을 알아봅니다.