반응형 이미지 미리 로드

Chrome 73부터 이미지를 더 빠르게 로드하기 위해 link rel="preload" 및 반응형 이미지를 결합할 수 있습니다.

브라우저 지원

  • 73
  • 79
  • 78
  • 17.2

이 도움말을 통해 제가 가장 좋아하는 두 가지 기능인 반응형 이미지 미리 로드에 대해 이야기해 보겠습니다. 이 두 가지 기능의 개발에 적극적으로 참여했던 사람으로서, 두 기능이 함께 작동하는 것을 보게 되어 매우 기쁩니다.

반응형 이미지 개요

너비가 300픽셀인 화면에서 웹을 탐색 중이며 페이지에서 너비가 1500픽셀인 이미지를 방금 요청했다고 가정해 보겠습니다. 추가 해상도로는 화면에서 아무것도 할 수 없기 때문에 해당 페이지에서 셀룰러 데이터가 많이 낭비되었습니다. 브라우저가 화면 크기(예: 325픽셀)보다 약간 더 넓은 이미지 버전을 가져오는 것이 이상적입니다. 이렇게 하면 데이터 낭비 없이 고해상도 이미지를 얻을 수 있습니다. 게다가 이미지가 더 빠르게 로드됩니다. 반응형 이미지를 사용하면 브라우저가 여러 이미지 리소스를 기기별로 가져올 수 있습니다. 이미지 CDN을 사용하지 않는 경우 각 이미지에 대해 여러 크기를 저장하고 srcset 속성에 지정해야 합니다. w 값은 각 버전의 너비를 브라우저에 알려줍니다. 기기에 따라 브라우저에서 적절한 옵션을 선택할 수 있습니다.

<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" alt="…">

미리 로드 개요

미리 로드를 사용하면 중요한 리소스가 HTML에서 발견되기 전에 최대한 빨리 로드하려는 정보를 브라우저에 알릴 수 있습니다. 이 기능은 스타일시트에 포함된 글꼴, 배경 이미지 또는 스크립트에서 로드된 리소스와 같이 쉽게 찾을 수 없는 리소스에 유용합니다.

<link rel="preload" as="image" href="important.png">

반응형 이미지 + 미리 로드 = 더 빠른 이미지 로드

반응형 이미지와 미리 로드는 지난 몇 년 동안 사용할 수 있었지만 그와 동시에 반응형 이미지를 미리 로드할 방법이 없었습니다. Chrome 73부터 브라우저에서 img 태그를 발견하기 전에 srcset에 지정된 반응형 이미지의 올바른 변형을 미리 로드할 수 있습니다.

사이트 구조에 따라 이미지가 훨씬 더 빠르게 표시될 수 있습니다. Google에서는 JavaScript를 사용하여 반응형 이미지를 지연 로드하는 사이트에서 테스트를 실행했습니다. 미리 로드로 인해 이미지가 1.2초 더 빠르게 로드되었습니다.

imagesrcsetimagesizes

반응형 이미지를 미리 로드하기 위해 최근 <link> 요소에 imagesrcsetimagesizes라는 새로운 속성이 추가되었습니다. <link rel="preload">와 함께 사용되며 <img> 요소에 사용되는 srcsetsizes 문법과 일치합니다.

예를 들어 다음과 같이 지정된 반응형 이미지를 미리 로드하려는 경우

 <img src="wolf.jpg" srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" sizes="50vw" alt="A rad wolf">

HTML의 <head>에 다음을 추가하면 됩니다.

<link rel="preload" as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw">

그러면 srcsetsizes가 적용되는 것과 동일한 리소스 선택 로직을 사용하여 요청이 시작됩니다.

사용 사례

동적으로 삽입된 반응형 이미지 미리 로드

슬라이드쇼의 일부로 히어로 이미지를 동적으로 로드하고 어떤 이미지가 먼저 표시될지 알고 있다고 가정해 보겠습니다. 이 경우 문제의 이미지를 로드하기 전에 스크립트를 기다리는 것을 피하는 것이 좋습니다. 이렇게 하면 사용자가 이미지를 볼 수 있을 때 지연되기 때문입니다.

동적으로 로드된 이미지 갤러리가 있는 웹사이트에서 이 문제를 검사할 수 있습니다.

  1. 새 탭에서 예시 웹사이트를 엽니다.

  2. `Control+Shift+J` (Mac의 경우 `Command+Option+J`)를 눌러 DevTools를 엽니다.

  3. 네트워크 탭을 클릭합니다.

  4. 제한 드롭다운 목록에서 Fast 3G를 선택합니다.

  5. 캐시 사용 중지 체크박스를 선택 해제합니다.

  6. 페이지를 새로고침합니다.

Chrome DevTools Network 패널의 스크린샷
이 폭포식 구조는 브라우저에서 스크립트 실행을 완료한 후에만 이미지가 로드되기 시작하므로 이미지가 처음 사용자에게 표시되는 시간에 불필요한 지연이 발생함을 보여줍니다.

preload를 사용하면 이미지가 미리 로드되기 시작하고 브라우저가 이미지를 표시해야 할 때 이미 있을 가능성이 높기 때문에 도움이 됩니다.

Chrome DevTools Network 패널의 스크린샷
이 폭포식 구조는 첫 번째 이미지가 스크립트와 동시에 로드되기 시작했음을 보여줍니다. 이로 인해 불필요한 지연이 방지되어 이미지가 더 빨리 표시됩니다.

미리 로드의 차이를 확인하려면 첫 번째 예의 단계에 따라 미리 로드된 첫 번째 이미지를 사용하여 동적으로 로드된 동일한 이미지 갤러리를 검사하면 됩니다.

image-set를 사용하여 배경 이미지 미리 로드

화면 밀도마다 다른 배경 이미지가 있는 경우 image-set 문법을 사용하여 CSS에서 이미지를 지정할 수 있습니다. 그러면 브라우저에서 화면의 DPR에 따라 표시할 것을 선택할 수 있습니다.

background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x);

CSS 배경 이미지의 문제는 CSS 배경 이미지가 많은 CSS일 수 있는 페이지의 <head>에 있는 모든 CSS를 다운로드하고 처리한 후에만 브라우저에서 발견한다는 것입니다.

반응형 배경 이미지가 있는 예시 웹사이트에서 이 문제를 검사할 수 있습니다.

Chrome DevTools Network 패널의 스크린샷
이 예에서는 CSS가 완전히 다운로드될 때까지 이미지 다운로드가 시작되지 않으므로 이미지 표시에 불필요한 지연이 발생합니다.

반응형 이미지 미리 로드를 사용하면 해킹 없이 이러한 이미지를 더 빠르게 로드할 수 있습니다.

<link rel="preload" as="image" imagesrcset="cat.png 1x, cat-2x.png 2x">

href 속성을 제외하면 <link> 요소에서 imagesrcset를 지원하지 않지만 CSS에서 image-set를 지원하는 브라우저가 잘못된 소스를 다운로드하지 않도록 할 수 있습니다. 그러나 이 경우 미리 로드의 이점을 누릴 수 없습니다.

미리 로드된 반응형 배경 이미지를 사용하여 이전 예가 어떻게 작동하는지 검사할 수 있습니다.

Chrome DevTools Network 패널의 스크린샷
여기에서 이미지와 CSS가 동시에 다운로드되기 때문에 지연을 방지하고 이미지 로드 속도가 빨라집니다.

실제 반응형 이미지 미리 로드

반응형 이미지를 미리 로드하면 이론상으로 이미지 속도가 빨라질 수 있지만 실제로는 어떤 효과가 있을까요?

그 질문에 답하기 위해 데모 PWA 매장의 사본 두 개를 만들었습니다. 이미지를 미리 로드하지 않는 사본이미지 중 일부를 미리 로드하는 사본입니다. 사이트는 자바스크립트를 사용하여 이미지를 지연 로드하므로 초기 표시 영역에 있는 이미지를 미리 로드하면 도움이 될 수 있습니다.

이를 통해 미리 로드 없음이미지 미리 로드에 대해 다음과 같은 결과를 얻었습니다. 원시 수치를 보면 렌더링 시작이 동일하게 유지되고 속도 색인이 약간 개선되었지만 (이미지가 더 빨리 도착하지만 픽셀 영역의 큰 부분은 차지하지 않기 때문에 273ms) Last Painted Hero 측정항목이 1.2초 개선되었음을 알 수 있습니다. 🎉🎉

물론 슬라이드 비교처럼 시각적인 차이를 보여주는 것은 없습니다.

미리 로드된 이미지가 약 1.5초 더 빠르게 표시되는 WebPageTest 슬라이드 비교 스크린샷
슬라이드를 통해 이미지가 미리 로드될 때 훨씬 더 빠르게 도착하여 사용자 환경이 크게 개선되었음을 알 수 있습니다.

미리 로드 및 <picture>하시겠어요?

반응형 이미지에 익숙하다면 <picture>은 어떨까요?

웹 성능 실무 그룹에서는 srcsetsizes에 상응하는 미리 로드를 추가하는 것에 관해 이야기하지만 '아트 디렉션' 사용 사례를 다루는 <picture> 요소는 추가하지 않습니다.

이 사용 사례가 '무시'되는 이유는 무엇인가요?

이러한 사용 사례를 해결하는 데 관심이 있지만, 여전히 해결해야 할 기술적 문제가 많이 있습니다. 이는 이런 솔루션에는 상당한 복잡성이 있음을 의미합니다. 그 밖에도 대부분의 경우 복잡하게 보이더라도 현재 사용 사례를 해결할 수 있을 것으로 보입니다 (아래 참고).

이 점을 감안하여 Web Performance WG는 srcset를 먼저 출시하고 이에 상응하는 picture 지원에 대한 수요가 발생하는지 확인하기로 결정했습니다.

<picture>를 미리 로드할 수 있는 위치에 있다면 다음 기법을 해결 방법으로 사용할 수 있습니다.

다음 시나리오의 경우:

<picture>
    <source srcset="small_cat.jpg" media="(max-width: 400px)">
    <source srcset="medium_cat.jpg" media="(max-width: 800px)">
    <img src="large_cat.jpg">
</picture>

<picture> 요소의 로직 (또는 정확하게 이미지 소스 선택 로직)은 <source> 요소의 media 속성을 순서대로 살펴보고 일치하는 첫 번째 속성을 찾은 다음 연결된 리소스를 사용하는 것입니다.

반응형 미리 로드에는 '순서' 또는 '첫 일치'의 개념이 없으므로 중단점을 다음과 같이 변환해야 합니다.

<link rel="preload" href="small_cat.jpg" as="image" media="(max-width: 400px)">
<link rel="preload" href="medium_cat.jpg" as="image" media="(min-width: 400.1px) and (max-width: 800px)">
<link rel="preload" href="large_cat.jpg" as="image" media="(min-width: 800.1px)">

미리 로드 및 type

<picture> 요소는 첫 번째 type에서의 일치도 지원하므로 다양한 이미지 형식을 제공하고 브라우저가 지원하는 첫 번째 이미지 형식을 선택할 수 있습니다. 이 사용 사례는 현재 미리 로드를 지원하지 않습니다.

이 기능을 사용하는 사이트의 경우 미리 로드를 피하는 것이 가장 좋은 옵션이며, 대신 미리 로드 스캐너<picture><source> 요소에서 선택하도록 합니다. 이 방법은 특히 우선순위 힌트를 지원하므로 미리 로드만 사용하는 것보다 더 나은 방식으로 적절한 이미지를 우선적으로 표시할 수 있습니다.

최대 콘텐츠 렌더링 시간 (LCP)에 미치는 영향

이미지는 최대 콘텐츠 렌더링 시간 (LCP)의 후보가 될 수 있으므로 이미지를 미리 로드하면 웹사이트의 LCP가 개선될 수 있습니다. 위의 기법을 사용하면 반응형 이미지를 더 빠르게 로드할 수도 있습니다.

미리 로드하는 이미지가 반응형인지 여부에 관계없이, 초기 마크업 페이로드에서 이미지 리소스를 검색할 수 없는 경우 미리 로드가 특히 잘 작동한다는 점에 유의하세요. 서버에서 완전한 마크업을 보내는 웹사이트의 경우 큰 이점을 누리지 못할 수 있습니다. 하지만 웹사이트가 브라우저에서 마크업을 렌더링하여 브라우저의 미리 로드된 스캐너를 우회하는 경우 표에 잠재적인 LCP 이미지를 미리 로드하여 성능을 개선할 수 있습니다.

요약

반응형 이미지 미리 로드는 이전에는 해킹을 통해서만 가능했던 방식으로 반응형 이미지를 미리 로드할 수 있는 새롭고 흥미로운 가능성을 제공합니다. 이는 속도에 민감한 개발자의 도구 상자에 새롭게 추가된 중요한 기능이며, 이를 통해 사용자에게 필요한 중요한 이미지를 최대한 빨리 제공할 수 있습니다.