lang/front

이미지 최적화.... 뭐가 이래 복잡해..

C/H 2018. 8. 16. 08:30

이미지 최적화

이미지 제거 및 바꾸기

  • 불필요한 이미지 리소스 제거
  • 가능한 경우 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);
    }
}
/* 브라우저가 해상도별 미디어 쿼리를 지원하지 않더라도 렌더링이 보장된다 */


반응형