이미지 최적화.... 뭐가 이래 복잡해..
이미지 최적화
이미지 제거 및 바꾸기
- 불필요한 이미지 리소스 제거
- 가능한 경우 CSS3 효과 활용
- 이미지에서 인코딩 텍스트 대신 웹 글꼴 사용
고해상도 화면의 영향
벡터이미지를 추천.
래스터 이미지를 사용해야한다면 srcset 및 picture를 사용하여 각 이미지에 대한 여러 버전을 제공하고 최적화.
<img src="lighthouse-200.jpg" sizes="50vw" srcset="lighthouse-100.jpg 100w, lighthouse-200.jpg 200w, lighthouse-400.jpg 400w, lighthouse-800.jpg 800w, lighthouse-1000.jpg 1000w, lighthouse-1400.jpg 1400w, lighthouse-1800.jpg 1800w" alt="a lighthouse"> <!-- 브라우저 너비와 기기 픽셀 비율에 따라 뷰포트 너비의 절반(sizes="50vw")인 이미지를 렌더링--> <!-- 브라우저 너비 기기 픽셀 비율 사용된 이미지 유효 해상도 400px 1 200.png 1x 400px 2 400.png 2x 320px 2 400.png 2.5x 600px 2 800.png 2.67x 640px 3 1000.png 3.125x 1100px 1 1400.png 1.27x --> <img src="400.png" sizes="(min-width: 600px) 25vw, (min-width: 500px) 50vw, 100vw" srcset="100.png 100w, 200.png 200w, 400.png 400w, 800.png 800w, 1600.png 1600w, 2000.png 2000w" alt="an example image"> <!-- 브라우저 너비가 600px 이상인 경우 이미지는 뷰포트 너비의 25%가 되고, 500px - 600px 사이인 경우 이미지는 뷰포트 너비의 50%가 되며, 500px 미만인 경우 이미지는 전체 너비가 된다. --> <picture> <source media="(min-width: 800px)" srcset="head.jpg, head-2x.jpg 2x"> <!--브라우저 너비가 최소 800px 이상, 기기 해상도에 따라 head.jpg 또는 head-2x.jpg가 사용--> <source media="(min-width: 450px)" srcset="head-small.jpg, head-small-2x.jpg 2x"> <!--450px 및 800px 사이, 기기 해상도에 따라 head-small.jpg 또는 head-small-2x.jpg가 사용--> <img src="head-fb.jpg" srcset="head-fb-2x.jpg 2x" alt="a head carved out of wood"> <!--450px 미만인 화면 너비는 picture 요소가 지원되지 않는 이전 버전과의 호환성을 위해, img 요소를 렌더링--> </picture>
압축이미지
압축 이미지 기법은 기기의 실제 성능에 상관없이 높은 압축율의 2x 이미지를 모든 기기에 제공. 이미지 유형과 압축 수준에 따라 파일 크기가 상당히 줄어들지만 화질은 별차이가 없어 보일 수 있다.
Caution압축 기법 사용 시 메모리가 늘어나고 디코딩 비용이 필요하므로 주의하세요. 작은 화면에 맞게 큰 이미지의 크기를 조정하는 것은 비용이 많이 들고, 메모리와 처리 성능이 모두 제한된 저사양 기기에서는 특히 손해가 클 수 있습니다.
자바스크립트 이미지 대체
자바스크립트 이미지 대체는 기기의 성능을 확인하고 '올바른 작업을 수행합니다'. window.devicePixelRatio
를 통해 기기 픽셀 비율을 결정하고, 화면 너비와 높이를 구할 수 있으며, 심지어 navigator.connection
을 통해 일부 네트워크 연결 스니핑을 수행하거나 가짜 요청을 발급할 수도 있습니다. 이 모든 정보를 수집한 경우 이제 로드할 이미지를 결정할 수 있습니다.
단점은 js가 payload 이벤트가 실행되지 전까지 이미지가 다운로드조차 되지 않는다.
데이터 URI
<img src="data:image/svg+xml;base64,[data]">
jpillora.com/base64-encoder와 같은 드래그 앤 드롭 도구를 사용하여, 이미지 등의 바이너리 파일을 데이터 URI로 변환할 수 있다.
CSS 이미지
- 디스플레이 특성에 맞는 최적의 이미지를 사용하고 화면 크기, 기기 해상도 및 페이지 레이아웃을 고려.
- 미디어 쿼리를 사용하는 높은 DPI 디스플레이의 경우 CSS에서 background-image 속성을 min-resolution 및 -webkit-min-device-pixel-ratio로 변경.
- 마크업에서 1x 이미지와 함께 고해상도 이미지를 제공하려면 srcset를 사용.
- 자바스크립트 이미지 대체 기법을 사용하거나 고압축 고해상도 이미지를 저해상도 기기에 제공할 경우에는 성능 비용을 고려.
.example { height: 400px; background-image: url(small.png); background-repeat: no-repeat; background-size: contain; background-position-x: center; } @media (min-width: 500px) { body { background-image: url(body.png); } .example { background-image: url(large.png); } }
image-set을 사용하여 고해상도 이미지 제공
2x 디스플레이에서 2x 이미지를 사용하거나,
제한된 대역폭 네트워크의 경우 2x 기기에서 1x 이미지를 사용
background-image: image-set( url(icon1x.jpg) 1x, url(icon2x.jpg) 2x ); /* 브라우저는 정확한 이미지를 로드할 뿐만 아니라 그에 따라 배율도 조정.
즉, 브라우저는 2x 이미지가 1x 이미지보다 두 배 더 크다고 가정하고 2의 배수 단위로 배율을 조정하므로, 해당 이미지가 동일한 크기로 페이지에 나타나다. */
image-set() 지원은 아직 새로운 기능이며 -webkit 공급업체 접두사가 있는 Chrome 및 Safari에서만 지원.
.sample { width: 128px; height: 128px; background-image: url(icon1x.png); background-image: -webkit-image-set( url(icon1x.png) 1x, url(icon2x.png) 2x ); background-image: image-set( url(icon1x.png) 1x, url(icon2x.png) 2x ); } /* 위에서는 image-set를 지원하는 브라우저에서 적절한 자산을 로드하며, 그렇지 않을 경우 1x 자산으로 폴백. 주의할 점은 image-set() 브라우저 지원이 부족한 경우에는 대부분의 브라우저가 1x 자산을 취한다. */
.sample { width: 128px; height: 128px; background-image: url(icon1x.png); } @media (min-resolution: 2dppx), /* Standard syntax */ (-webkit-min-device-pixel-ratio: 2) /* Safari & Android Browser */ { .sample { background-size: contain; background-image: url(icon2x.png); } } /* 브라우저가 해상도별 미디어 쿼리를 지원하지 않더라도 렌더링이 보장된다 */