가변 픽셀 밀도를 위한 높은 DPI 이미지

오늘날의 복잡한 기기 환경의 특징 중 하나는 매우 다양한 화면 픽셀 밀도를 사용할 수 있다는 것입니다. 일부 기기에는 매우 높은 해상도의 디스플레이가 탑재되어 있는 반면 다른 기기는 뒤처져 있습니다. 애플리케이션 개발자는 다양한 픽셀 밀도를 지원해야 하며, 이는 매우 어려울 수 있습니다. 모바일 웹의 과제는 다음과 같은 여러 요인으로 악화됩니다.

  • 다양한 폼 팩터의 다양한 기기
  • 제한된 네트워크 대역폭과 배터리 수명

이미지 측면에서 웹 앱 개발자의 목표는 최상의 품질의 이미지를 최대한 효율적으로 제공하는 것입니다. 이 문서에서는 현재와 가까운 미래에 이 작업을 실행하는 데 유용한 몇 가지 기술을 설명합니다.

가능하면 이미지를 사용하지 마세요.

이 웜을 열기 전에, 웹에는 해상도 및 DPI에 영향을 받지 않는 강력한 기술이 많이 있다는 점을 기억하세요. 구체적으로는 웹의 자동 픽셀 확장 기능 (devicePixelRatio를 통해)으로 인해 텍스트, SVG 및 대부분의 CSS가 '작동'합니다.

하지만 래스터 이미지를 항상 피할 수는 없습니다. 예를 들어 순수 SVG/CSS로 재현하기 매우 어려운 애셋이 주어졌거나 사진을 처리하는 경우일 수 있습니다. 이미지를 SVG로 자동 변환할 수는 있지만, 확대된 버전이 일반적으로 보기 좋지 않으므로 사진을 벡터화하는 것은 거의 의미가 없습니다.

배경

디스플레이 밀도의 역사가 매우 짧음

초기에는 컴퓨터 디스플레이의 픽셀 밀도가 72 또는 96dpi(인치당 도트 수)였습니다.

디스플레이의 픽셀 밀도가 점차적으로 개선되었습니다. 모바일 사용 사례에서 주를 이루었습니다. 모바일 사용 사례에서는 일반적으로 사용자가 휴대전화를 얼굴에 더 가까이 대면 픽셀이 더 잘 보입니다. 2008년에는 150dpi 휴대전화가 새로운 표준이 되었습니다. 디스플레이 밀도 증가 추세는 계속되었으며 오늘날 신형 휴대전화는 300dpi 디스플레이 (Apple에서 브랜드 'Retina')를 사용합니다.

물론 궁극적인 목표는 픽셀이 완전히 보이지 않는 디스플레이입니다. 휴대전화 폼 팩터의 경우 현재 세대의 Retina/HiDPI 디스플레이가 이러한 이상에 가까울 수 있습니다. 하지만 Project Glass와 같은 새로운 유형의 하드웨어 및 웨어러블 기기는 계속해서 픽셀 밀도를 높일 가능성이 높습니다.

실제로 저밀도 이미지는 새 화면에서 이전 화면과 동일하게 표시되어야 하지만, 고밀도 사용자가 익숙한 선명한 이미지에 비해 저밀도 이미지는 거칠고 모자이크 현상이 발생합니다. 다음은 1x 이미지가 2x 디스플레이에 표시되는 방식을 대략적으로 시뮬레이션한 것입니다. 반면에 2x 이미지는 상당히 보기 좋습니다.

개코원숭이 1개
Baboon 2x
다양한 픽셀 밀도의 원숭이

웹 Pixel

웹이 설계될 당시 디스플레이의 99%가 96dpi였으며(또는 96dpi인 것처럼 보임) 이 부분에 대한 변형을 위한 조치는 거의 없었습니다. 화면 크기와 밀도가 크게 다르기 때문에 다양한 화면 밀도와 크기에서 이미지가 잘 보이도록 하는 표준적인 방법이 필요했습니다.

HTML 사양은 최근 제조업체가 CSS 픽셀의 크기를 결정하는 데 사용하는 참조 픽셀을 정의하여 이 문제를 해결했습니다.

제조업체는 참조 픽셀을 사용하여 표준 또는 이상적인 픽셀을 기준으로 기기의 실제 픽셀 크기를 결정할 수 있습니다. 이 비율을 기기 픽셀 비율이라고 합니다.

기기 픽셀 비율 계산

스마트폰의 화면 실제 픽셀 크기가 180ppi라고 가정해 보겠습니다. 기기 픽셀 비율을 계산하는 데는 세 단계가 필요합니다.

  1. 기기가 잡힌 실제 거리를 참조 픽셀의 거리와 비교합니다.

    사양에 따르면 28인치에서는 이상적인 인치당 96픽셀입니다. 하지만 스마트폰이기 때문에 사람들은 노트북을 쥐는 것보다 얼굴에 더 가까이 기기를 댑니다. 이 거리를 18인치로 추정해 보겠습니다.

  2. 거리 비율을 표준 밀도(96ppi)에 곱하여 주어진 거리에 적합한 이상적인 픽셀 밀도를 구합니다.

    idealPixelDensity = (28/18) * 96 = 인치당 150픽셀(약)

  3. 실제 픽셀 밀도와 이상적인 픽셀 밀도의 비율을 사용하여 기기 픽셀 비율을 구합니다.

    devicePixelRatio = 180/150 = 1.2

devicePixelRatio 계산 방법
devicePixelRatio가 계산되는 방식을 보여주는 참조 각도 픽셀 1개를 보여주는 다이어그램입니다.

이제 브라우저가 이상적인 해상도 또는 표준 해상도에 따라 화면에 맞게 이미지 크기를 조절하는 방법을 알아야 할 때 브라우저는 기기 픽셀 비율 1.2를 참조합니다. 즉, 이 기기에는 이상적인 픽셀마다 실제 픽셀 1.2가 있습니다. 이상적인 픽셀(웹 사양에 정의된 대로)과 실제 픽셀 (기기 화면의 점) 간에 구하는 공식은 다음과 같습니다.

physicalPixels = window.devicePixelRatio * idealPixels

이전에는 기기 공급업체가 devicePixelRatios(DPR)을 반올림하는 경향이 있었습니다. Apple의 iPhone 및 iPad는 DPR 1을 보고하고 Retina 등가 기기는 2를 보고합니다. CSS 사양에서는 다음을 권장합니다.

픽셀 단위는 참조 픽셀에 가장 근접한 기기 픽셀의 정수를 나타냅니다.

원형 비율이 더 나을 수 있는 한 가지 이유는 하위 픽셀 아티팩트가 줄어들 수 있기 때문입니다.

그러나 실제 기기 환경은 훨씬 더 다양하며 Android 휴대전화의 DPR은 1.5인 경우가 많습니다. Nexus 7 태블릿의 DPR은 약 1.33이며 이는 위와 유사한 계산을 통해 도출되었습니다. 앞으로 DPR이 가변적인 기기가 더 많이 등장할 것으로 예상됩니다. 따라서 클라이언트가 정수 DPR을 가질 것이라고 가정해서는 안 됩니다.

HiDPI 이미지 기법 개요

최상의 품질의 이미지를 최대한 빨리 표시하는 문제를 해결하는 데는 여러 기법이 있으며, 크게 두 가지 카테고리로 나뉩니다.

  1. 단일 이미지 최적화
  2. 여러 이미지 간의 선택 최적화

단일 이미지 접근 방식: 하나의 이미지를 사용하지만 똑똑하게 사용합니다. 이러한 접근 방식은 DPI가 낮은 이전 기기에서도 HiDPI 이미지를 다운로드하므로 성능이 저하된다는 단점이 있습니다. 다음은 단일 이미지 사례에 대한 몇 가지 접근 방식입니다.

  • 심하게 압축된 HiDPI 이미지
  • 완전히 멋진 이미지 형식
  • 프로그레시브 이미지 형식

여러 이미지 접근 방식: 여러 이미지를 사용하지만 스마트하게 로드할 이미지를 선택합니다. 이러한 접근 방식에는 개발자가 동일한 애셋의 여러 버전을 만든 다음 결정 전략을 파악하는 데 내재된 오버헤드가 있습니다. 선택할 수 있는 옵션은 다음과 같습니다.

  • 자바스크립트
  • 서버 측 전송
  • CSS 미디어 쿼리
  • 브라우저 내장 기능 (image-set(), <img srcset>)

심하게 압축된 HiDPI 이미지

이미지는 이미 평균 웹사이트를 다운로드하는 데 소비되는 대역폭의 60%를 차지합니다. 모든 클라이언트에 HiDPI 이미지를 제공하여 이 숫자를 늘릴 예정입니다. 얼마나 더 커지나요?

90, 50, 20에서 JPEG 품질의 1x 및 2x 이미지 프래그먼트를 생성하는 몇 가지 테스트를 실행했습니다. 다음은 이를 생성하는 데 사용한 셸 스크립트(ImageMagick 사용)입니다.

카드 예시 1 카드 예시 2 카드 예 3
다양한 압축 및 픽셀 밀도의 이미지 샘플

이 작고 비과학적인 샘플링을 통해 대용량 이미지를 압축하면 품질과 크기 간의 균형이 잘 잡히는 것으로 보입니다. 제 눈에는 과도하게 압축된 2배 이미지가 압축되지 않은 1배 이미지보다 실제로 더 좋아 보입니다.

물론 화질이 낮고 압축률이 높은 2배 이미지를 2배 크기의 기기에 게재하는 것은 화질이 더 높은 이미지를 게재하는 것보다 좋지 않으며 위의 접근 방식은 이미지 품질 저하를 초래합니다. 품질: 90 이미지와 품질: 20 이미지를 비교하면 선명도가 떨어지고 입자가 증가하는 것을 볼 수 있습니다. 고품질 이미지가 중요한 경우(예: 사진 뷰어 애플리케이션) 또는 타협하고 싶지 않은 앱 개발자의 경우 이러한 아티팩트가 허용되지 않을 수 있습니다.

위의 비교는 압축된 JPEG로만 이루어졌습니다. 널리 구현된 이미지 형식(JPEG, PNG, GIF)에는 많은 장단점이 있습니다.

완전히 멋진 이미지 형식

WebP는 높은 이미지 충실도를 유지하면서 매우 잘 압축하는 매우 매력적인 이미지 형식입니다. 물론 아직 모든 곳에 구현되지는 않습니다.

한 가지 방법은 자바스크립트를 통해 WebP 지원을 확인하는 것입니다. data-uri를 통해 1픽셀 이미지를 로드하고 로드 또는 오류 이벤트가 발생할 때까지 기다린 다음 크기가 올바른지 확인합니다. Modernizr에는 이러한 기능 감지 스크립트가 제공되며, 이 스크립트는 Modernizr.webp를 통해 사용할 수 있습니다.

하지만 이 작업을 수행하는 더 좋은 방법은 image() 함수를 사용하여 CSS에서 직접 사용하는 것입니다. 따라서 WebP 이미지와 JPEG 대체 항목이 있는 경우 다음과 같이 작성할 수 있습니다.

#pic {
  background: image("foo.webp", "foo.jpg");
}

이 접근 방식에는 몇 가지 문제가 있습니다. 첫째, image()는 널리 구현되지 않았습니다. 둘째, WebP 압축은 JPEG를 압도하지만 여전히 상대적으로 점진적인 개선입니다. 이 WebP 갤러리를 기준으로 약 30% 더 작습니다. 따라서 WebP만으로는 높은 DPI 문제를 해결하기에 충분하지 않습니다.

프로그레시브 이미지 형식

JPEG 2000, 프로그레시브 JPEG, 프로그레시브 PNG, GIF와 같은 프로그레시브 이미지 형식은 이미지가 완전히 로드되기 전에 이미지가 미리 구현되는 것을 볼 수 있다는 장점이 있습니다. 크기 오버헤드가 발생할 수 있지만 이에 관한 증거는 상충합니다. 프로그레시브 모드는 'PNG 이미지의 크기를 약 20%, JPEG 및 GIF 이미지의 크기를 약 10% 늘립니다'라고 제프 애트우드가 주장했습니다. 그러나 대용량 파일의 경우 대부분의 경우 프로그레시브 모드가 더 효율적이라고 Stoyan Stefanov가 주장했습니다.

언뜻 보기에는 프로그레시브 이미지가 최고의 품질의 이미지를 최대한 빠르게 게재하는 맥락에서 매우 유망해 보입니다. 추가 데이터로 이미지 품질이 개선되지 않는다는 것을 알게 되면 브라우저가 이미지 다운로드 및 디코딩을 중지할 수 있습니다(즉, 모든 화질 개선이 하위 픽셀 수준임).

연결은 쉽게 종료할 수 있지만 다시 시작하는 데는 비용이 많이 드는 경우가 많습니다. 이미지가 많은 사이트의 경우 가장 효율적인 방법은 단일 HTTP 연결을 가능한 한 오랫동안 재사용하여 활성 상태로 유지하는 것입니다. 하나의 이미지가 충분히 다운로드되어 연결이 조기에 종료되면 브라우저는 새 연결을 만들어야 하는데, 이는 지연 시간이 짧은 환경에서 매우 느릴 수 있습니다.

이에 대한 한 가지 해결 방법은 브라우저가 가져올 바이트 범위를 지정할 수 있는 HTTP Range 요청을 사용하는 것입니다. 스마트 브라우저는 HEAD 요청을 실행하여 헤더를 가져오고, 처리하고, 실제로 필요한 이미지의 양을 결정한 다음 가져올 수 있습니다. 안타깝게도 HTTP 범위는 웹 서버에서 제대로 지원되지 않기 때문에 비효율적입니다.

마지막으로 이 접근 방식의 명백한 한계는 로드할 이미지를 선택할 수 없고 동일한 이미지의 다양한 충실도를 선택할 수 있다는 것입니다. 따라서 '아트 디렉션' 사용 사례는 다루지 않습니다.

자바스크립트를 사용하여 로드할 이미지 결정

로드할 이미지를 결정하는 첫 번째이자 가장 명백한 접근 방식은 클라이언트에서 JavaScript를 사용하는 것입니다. 이 접근 방식을 사용하면 사용자 에이전트에 관한 모든 정보를 확인하고 적절한 조치를 취할 수 있습니다. window.devicePixelRatio를 통해 기기 픽셀 비율을 결정하고, 화면 너비와 높이를 가져올 수 있으며, 심지어 navigator.connection을 통해 일부 네트워크 연결 스니핑을 수행하거나 foresight.js 라이브러리와 같이 가짜 요청을 발급할 수도 있습니다. 이 모든 정보를 수집했다면 이제 로드할 이미지를 결정할 수 있습니다.

위와 같은 작업을 하는 JavaScript 라이브러리는 약 100만 개가 있으며, 안타깝게도 그중에서 뛰어난 라이브러리는 없습니다.

이 접근 방식의 큰 단점 중 하나는 JavaScript를 사용하면 미리 보기 파서가 완료될 때까지 이미지 로드가 지연된다는 것입니다. 즉, pageload 이벤트가 실행되기 전까지는 이미지 다운로드조차 시작되지 않습니다. 자세한 내용은 제이슨 그리그스비의 도움말을 참고하세요.

서버에 로드할 이미지 결정

제공하는 이미지마다 커스텀 요청 핸들러를 작성하여 서버 측 결정을 연기할 수 있습니다. 이러한 핸들러는 사용자 에이전트 (서버에 전달되는 유일한 정보)를 기반으로 Retina 지원을 확인합니다. 그런 다음 서버 측 로직에서 HiDPI 애셋을 제공할지 여부에 따라 적절한 애셋(알려진 약속에 따라 이름 지정됨)을 로드합니다.

안타깝게도 사용자 에이전트는 기기가 고품질 또는 저품질 이미지를 수신해야 하는지 결정하는 데 충분한 정보를 제공하지 않을 수도 있습니다. 또한 사용자-에이전트와 관련된 모든 것은 해킹이며 가능한 한 피해야 한다고 설명합니다.

CSS 미디어 쿼리 사용

선언적 방식이므로 CSS 미디어 쿼리를 사용하면 의도를 선언하고 브라우저가 대신 올바른 작업을 하도록 할 수 있습니다. 미디어 쿼리의 가장 일반적인 사용법인 기기 크기 일치 외에도 devicePixelRatio를 일치시킬 수도 있습니다. 연결된 미디어 쿼리는 device-pixel-ratio이며 예상대로 최솟값 및 최댓값 변형이 연결되어 있습니다. 고 DPI 이미지를 로드하려고 하는데 기기 픽셀 비율이 임곗값을 초과하는 경우 다음을 수행할 수 있습니다.

#my-image { background: (low.png); }

@media only screen and (min-device-pixel-ratio: 1.5) {
  #my-image { background: (high.png); }
}

특히 'min'과 'max' 프리픽스의 배치가 엄청나게 다르기 때문에 모든 공급업체 프리픽스가 섞여 있으면 조금 더 복잡해집니다.

@media only screen and (min--moz-device-pixel-ratio: 1.5),
    (-o-min-device-pixel-ratio: 3/2),
    (-webkit-min-device-pixel-ratio: 1.5),
    (min-device-pixel-ratio: 1.5) {

  #my-image {
    background:url(high.png);
  }
}

이 접근 방식을 사용하면 JS 솔루션에서 사라진 선행 파싱의 이점을 다시 얻을 수 있습니다. 또한 서버 측 접근 방식에서는 사용할 수 없었던 반응형 중단점을 유연하게 선택할 수 있습니다(예: 낮은, 중간, 높은 DPI 이미지를 사용할 수 있음).

안타깝게도 아직은 다소 불편하고 이상한 모양의 CSS가 생성되거나 사전 처리가 필요합니다. 또한 이 접근 방식은 CSS 속성으로 제한되므로 <img src>를 설정할 방법이 없으며 이미지가 모두 배경이 있는 요소여야 합니다. 마지막으로 기기 픽셀 비율만 엄격하게 사용하면 EDGE 연결 상태에서 고DPI 스마트폰이 대용량 2배 이미지 애셋을 다운로드하는 상황이 발생할 수 있습니다. 이는 최적의 사용자 환경이 아닙니다.

새로운 브라우저 기능 사용하기

최근 고DPI 이미지 문제에 대한 웹 플랫폼 지원에 관해 많은 논의가 있었습니다. Apple은 최근 image-set() CSS 함수를 WebKit에 도입하여 이 분야에 진출했습니다. 따라서 Safari와 Chrome 모두 지원합니다. image-set()는 CSS 함수이므로 <img> 태그의 문제를 해결하지 않습니다. 이 문제를 해결하지만 (이 글을 작성하는 시점에서는) 아직 참조 구현이 없는 @srcset을 입력합니다. 다음 섹션에서는 image-setsrcset에 관해 자세히 알아봅니다.

높은 DPI 지원을 위한 브라우저 기능

궁극적으로 어떤 접근 방식을 사용할지는 특정 요구사항에 따라 결정됩니다. 하지만 앞서 언급한 모든 접근 방식에는 단점이 있습니다. 하지만 앞으로 image-set 및 srcset이 광범위하게 지원되면 이 문제에 적절한 해결책이 될 것입니다. 지금은 이 이상적인 미래에 최대한 가까워질 수 있는 몇 가지 권장사항을 살펴보겠습니다.

먼저 두 가지의 차이점은 무엇인가요? image-set()는 배경 CSS 속성의 값으로 사용하기에 적합한 CSS 함수입니다. srcset은 <img> 요소에만 적용되는 속성으로 유사한 문법을 사용합니다. 이 두 태그 모두 이미지 선언을 지정할 수 있지만 srcset 속성을 사용하면 뷰포트 크기를 기반으로 로드할 이미지를 구성할 수도 있습니다.

이미지 세트 권장사항

image-set() CSS 함수는 -webkit-image-set() 접두사로 사용할 수 있습니다. 구문은 매우 간단합니다. 쉼표로 구분된 이미지 선언을 하나 이상 사용합니다. 이러한 선언은 URL 문자열 또는 url() 함수와 관련 해상도로 구성됩니다. 예를 들면 다음과 같습니다.

background-image:  -webkit-image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);

이렇게 하면 브라우저에 선택할 수 있는 이미지가 두 개 있다고 알립니다. 하나는 1x 디스플레이에 최적화되어 있고 다른 하나는 2x 디스플레이에 최적화되어 있습니다. 그런 다음 브라우저가 충분히 스마트한 경우 (현재 구현되지 않은 경우) 다양한 요인에 따라 로드할 브라우저를 선택합니다. 여기에는 네트워크 속도도 포함될 수 있습니다.

브라우저는 정확한 이미지를 로드할 뿐만 아니라 그에 따라 배율도 조정합니다. 즉, 브라우저는 2x 이미지가 1x 이미지보다 두 배 더 크다고 가정하고 2의 배수 단위로 배율을 조정하므로, 해당 이미지가 페이지에서 동일한 크기로 표시됩니다.

1x, 1.5x 또는 Nx를 지정하는 대신 특정 기기 픽셀 밀도를 dpi로 지정할 수도 있습니다.

이는 image-set 속성을 지원하지 않는 브라우저를 제외하고 잘 작동합니다. 이러한 브라우저에서는 이미지가 전혀 표시되지 않습니다. 이는 분명히 좋지 않으므로 대체(또는 일련의 대체)를 사용하여 이 문제를 해결해야 합니다.

background-image: url(icon1x.jpg);
background-image: -webkit-image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);
/* This will be useful if image-set gets into the platform, unprefixed.
    Also include other prefixed versions of this */
background-image: image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);

위에서는 image-set를 지원하는 브라우저에서 적절한 애셋을 로드하고, 그렇지 않으면 1x 애셋으로 대체합니다. 주의할 점은 image-set() 브라우저 지원이 부족한 경우에는 대부분의 사용자 에이전트가 1x 애셋을 가져온다는 것입니다.

이 데모에서는 image-set()를 사용하여 올바른 이미지를 로드하고 이 CSS 함수가 지원되지 않는 경우 1x 애셋으로 대체합니다.

이 시점에서 image-set()를 폴리필(즉, JavaScript shim 빌드)하고 끝내면 되지 않을까 궁금하실 수 있습니다. CSS 함수에 효율적인 폴리필을 구현하는 것은 매우 어렵습니다. (그 이유에 관한 자세한 설명은 이 www 스타일 논의를 참고하세요.)

이미지 srcset

다음은 srcset의 예입니다.

<img alt="my awesome image"
  src="banner.jpeg"
  srcset="banner-HD.jpeg 2x, banner-phone.jpeg 640w, banner-phone-HD.jpeg 640w 2x">

보시다시피 srcset 요소는 image-set에서 제공하는 x 선언 외에도 뷰포트 크기에 해당하는 w 및 h 값을 사용하여 가장 관련성 높은 버전을 게재하려고 시도합니다. 위의 경우 표시 영역 너비가 640px 미만인 기기에 banner-phone-HD.jpeg, 화면이 높은 DPI 기기의 경우 banner-phone-HD.jpeg, 화면이 640px를 초과하는 높은 DPI 기기에는 banner-HD.jpeg, 그 외 모든 기기에는 banner.jpeg가 게재됩니다.

이미지 요소에 image-set 사용

img 요소의 srcset 속성은 대부분의 브라우저에서 구현되지 않으므로 img 요소를 배경이 있는 <div>로 바꾸고 이미지 세트 접근 방식을 사용하고 싶을 수 있습니다. 단, 몇 가지 예외가 있습니다. 단점은 <img> 태그에 오래된 시맨틱 값이 있다는 점입니다. 실제로 이는 주로 웹 크롤러와 접근성 측면에서 중요합니다.

-webkit-image-set를 사용하게 되면 background CSS 속성을 사용하고 싶을 수 있습니다. 이 접근 방식의 단점은 이미지 크기를 지정해야 한다는 점입니다. 1x가 아닌 이미지를 사용하는 경우 크기를 알 수 없습니다. 이렇게 하는 대신 다음과 같이 content CSS 속성을 사용할 수 있습니다.

<div id="my-content-image"
  style="content: -webkit-image-set(
    url(icon1x.jpg) 1x,
    url(icon2x.jpg) 2x);">
</div>

그러면 devicePixelRatio를 기반으로 이미지가 자동으로 크기 조절됩니다. image-set를 지원하지 않는 브라우저의 경우 url()로 추가 대체되는 위 기술의 작동 방식을 보여주는 이 예를 참고하세요.

srcset 폴리필

srcset의 유용한 기능 중 하나는 자연스러운 대체 옵션이 제공된다는 점입니다. srcset 속성이 구현되지 않은 경우 모든 브라우저가 src 속성을 처리해야 합니다. 또한 이는 단순히 HTML 속성이므로 JavaScript로 폴리필을 만들 수 있습니다.

이 폴리필은 사양에 최대한 근접하도록 단위 테스트와 함께 제공됩니다. 또한 srcset가 기본적으로 구현된 경우 polyfill이 코드를 실행하지 못하도록 하는 검사가 있습니다.

다음은 실제로 작동하는 polyfill의 데모입니다.

결론

높은 DPI 이미지의 문제를 해결할 수 있는 특별한 방법은 없습니다.

가장 쉬운 해결책은 이미지를 전혀 사용하지 않고 대신 SVG와 CSS를 선택하는 것입니다. 하지만 사이트에 고품질 이미지가 있는 경우에는 항상 실현 가능한 것은 아닙니다.

JS, CSS, 서버 측 접근방식에는 모두 장단점이 있습니다. 하지만 가장 유망한 접근 방식은 새 브라우저 기능을 활용하는 것입니다. image-setsrcset에 대한 브라우저 지원은 아직 불완전하지만 현재 사용할 수 있는 적절한 대체 방법이 있습니다.

요약하면 다음과 같은 권장사항을 보내드립니다.

  • 배경 이미지의 경우 이를 지원하지 않는 브라우저를 위한 적절한 대체 옵션과 함께 image-set을 사용하세요.
  • 콘텐츠 이미지의 경우 srcset polyfill을 사용하거나 image-set 사용(위 참고)으로 대체합니다.
  • 이미지 품질을 포기해야 한다면 크게 압축된 2배 이미지를 사용하는 것이 좋습니다.