반응형 이미지 제대로 사용해보자!

제리님·2019년 10월 24일
11
post-thumbnail

서론

이미지가 많이 들어가는 페이지를 제작하기에 앞서 페이지에 2.3M짜리 이미지가 들어간 것을 보고 이대론 안되겠다 싶어 효과적인 UX를 위해
https://images.guide/를 읽고서 반응형 사이트에서 이미지 최적화를 제대로 하기위해 공유하기 위해 작성합니다.

반응형 이미지를 사용시 고려해야할 사항

  1. 이미지 크기(size)와 관련한 성능/속도 및 대역폭 문제
    //비슷한 퀄리티의 이미지에 많은 용량이 큰 이미지를 사용하지 말자.
  2. 고밀집도(High-DPI) 디바이스 대응
    //device 마다 DPR이 다르다기에 맞는 이미지를 제공해야한다.
  3. 아트 디렉션(art direction) 처리

  1. 이미지 포맷 대응
    //밑에서 추가 설명

태그 사용

  1. 이미지 크기(size)와 관련한 성능/속도 및 대역폭 문제
  2. 고밀집도(High-DPI) 디바이스 대응
  3. 아트 디렉션(art direction) 처리

위의 문제들은 태그와 srcset등을 사용하여 해결 할 수 있을꺼라 생각합니다.

The browser itself is capable of choosing which image format to display through the use of the tag. The tag utilizes multiple elements, with one tag, which is the actual DOM element which contains the image. The browser cycles through the sources and retrieves the first match. If the tag isn’t supported in the user’s browser, a

is rendered and the tag is used.

브라우저 자체는 태그를 사용하여 표시 할 이미지 형식을 선택할 수 있습니다. 태그는 여러 개의 와 하나의 태그(이미지를 포한하는 실제 DOM)를 활용 할 수 있습니다. 브라우저는 소스를 순환하며 첫 번째 일치 항목을 검색합니다. 만약 태그가 브라우저에서 지원되지 않으면,

이 렌더링되고 태그가 사용됩니다.

예제

  <picture>
	<source
		media="(min-width: 1280px)"
		sizes="50vw"
		srcset="opera-fullshot-200.webp 200w,
				opera-fullshot-400.webp 400w,
				opera-fullshot-800.webp 800w,
				opera-fullshot-1200.webp 1200w,
				opera-fullshot-1600.webp 1600w,
				opera-fullshot-2000.webp 2000w"
		type="image/webp">
	<source
		sizes="(min-width: 640px) 60vw, 100vw"
		srcset="opera-closeup-200.webp 200w,
				opera-closeup-400.webp 400w,
				opera-closeup-800.webp 800w,
				opera-closeup-1200.webp 1200w,
				opera-closeup-1600.webp 1600w,
				opera-closeup-2000.webp 2000w"
		type="image/webp">
	<source
		media="(min-width: 1280px)"
		sizes="50vw"
		srcset="opera-fullshot-200.jpg 200w,
				opera-fullshot-400.jpg 400w,
				opera-fullshot-800.jpg 800w,
				opera-fullshot-1200.jpg 1200w,
				opera-fullshot-1600.jpg 1800w,
				opera-fullshot-2000.jpg 2000w">
	<img
		src="opera-closeup-400.jpg" alt="The Oslo Opera House"
		sizes="(min-width: 640px) 60vw, 100vw"
		srcset="opera-closeup-200.jpg 200w,
				opera-closeup-400.jpg 400w,
				opera-closeup-800.jpg 800w,
				opera-closeup-1200.jpg 1200w,
				opera-closeup-1600.jpg 1600w,
				opera-closeup-2000.jpg 2000w">
</picture>

태그에 들어가는 속성

> srcset "이미지와 vw(viewport width)를 이용하여 vw별로 이미지를 지정할 수 있습니다.
> sizes 이미지의 사이즈를 결정합니다. (min-width: 640px) 60vw, 100vw는 vw가 min-width : 640px 가 true라면 60vw,아니라면 100vw를 설정하라는 의미입니다.
> media @media 와 동일합니다.
> type type="image/webp"를 통해 지원 가능한 브라우저라면 webp를 사용할 수 있게 해줍니다.
!! img태그는 항상 마지막에 있어야 합니다.!!

이곳에 아주 좋은 예제가 있습니다. https://dev.opera.com/articles/responsive-images/

4. 이미지 포맷 대응

.webp

브라우저가 지원한다면 우선적으로 사용할 예정입니다.
WebP is a recent image format from Google aiming to offer lower file-sizes for lossless and lossy compression at an acceptable visual quality. It includes support for alpha-channel transparency and animation.

Webp은 허용 가능한 시각적 품질로 무손실 및 손실 압축을 위해 더 작은 파일 크기를 제공하는 것을 목표로하는 Google의 최신 이미지 형식입니다. 알파 채널 투명성과 애니메이션을 지원합니다.

imagine-webp example

const imagemin = require('imagemin');
const imageminWebp = require('imagemin-webp');

(async () => {
	await imagemin(['images/*.{jpg,png}'], 'build/images', {
		use: [
			imageminWebp({quality: 50})
		]
	});

	console.log('Images optimized');
})();

https://github.com/imagemin/imagemin-webp

.JPEG

webP를 지원하지 않는 브라우저에서 Jpeg의 경우 MozJpeg를 사용할 예정입니다.

Mozilla offers a modernized JPEG encoder in the form of MozJPEG. It claims to shave up to 10% off JPEG files. Files compressed with MozJPEG work cross-browser and some of its features include progressive scan optimization, trellis quantization (discarding details that compress the least) and a few decent quantization table presets that help create smoother High-DPI images (although this is possible with ImageMagick if you’re willing to wade through XML configurations).

Mozilla는 MozJPEG 형식으로 현대화 된 JPEG 인코더를 제공합니다 . 이 주장 JPEG 파일을 10 % 할인까지 면도 할 수 있습니다. MozJPEG로 압축 된 파일은 크로스 브라우저로 작동하며 일부 기능에는 점진적 스캔 최적화, 격자 양자화 (최소 압축률은 가장 적은 압축 제거) 및 매끄러운 고 DPI 이미지를 생성하는 데 도움이되는 적절한 양자화 테이블 사전 설정 이 포함됩니다 (ImageMagick으로 가능하더라도) XML 구성을 기꺼이 감수하려는 경우).

const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');

(async () => {
  await imagemin(['images/*.jpg'], 'build/images', {
      use: [
          imageminMozjpeg()
      ]
  });

  console.log('Images optimized');
})();

https://www.npmjs.com/package/imagemin-mozjpeg

또한 Progressive JPEG 를 이용하여 사용자 접근을 빠르게 하려합니다.

PJPEG가 이미지를로드 할 때 저해상도 '미리보기'를 제공하는 능력은 인식 된 성능을 향상시킵니다. 사용자는 적응 형 이미지에 비해 이미지가 더 빨리로드되는 것처럼 느낄 수 있습니다.

.PNG

webP를 지원하지 않는 브라우저에서 png인 경우 pngquant를 사용할 예정입니다.
https://www.npmjs.com/package/imagemin-pngquant
JPEG->Mozjpeg,webp,P rogressive JPEG

GIF

git의 경우 ffmpeg 를 사용 하여 애니메이션 GIF (또는 소스)를 H.264 MP4로 변환하십시오 라고 추천합니다.

.SVG

svg는 svgo를 사용하여 최적화 할 예정입니다.

const imagemin = require('imagemin');
const imageminSvgo = require('imagemin-svgo');

(async () => {
	await imagemin(['images/*.svg'], 'build/images', {
		use: [
			imageminSvgo({
				plugins: [
					{removeViewBox: false}
				]
			})
		]
	});

	console.log('Images optimized');
})();

https://www.npmjs.com/package/imagemin-svgo

Native lazy-loading for the web

를 사용하고 싶지만 아직 chrome과 firefox를 지원하므로
lazysize를 사용할 예정입니다.

그 외에 고려할만한 도구
nextjs 에서 빌드시 이미지를 최적화 해주는 라이브러리
선택적으로 사용가능하다.
https://www.npmjs.com/package/next-optimized-images

Example

import React from 'react';
import 'lazysizes/plugins/attrchange/ls.attrchange';
lazysizes를 react에서 사용하기 위해 불러온후
srcset대신에 data-srcset, ser대신에 data-src를 사용하면됩니다

webp를 지원할때(chrmoe 브라우저) 1024px이상에서는 service_PC.webp 700이상은 service_m.webp
700 미만은 service_m.png 가 될것입니다.

chrome-test


webp를 지원안할때(safari) 700이하에서는 service_m.png 그외에는 service_PC.jpg가 나올것입니다.

safari-test


webp를 지원하지않을때 받는 원본 png의 크기는 4.8M의크기고 webp는 240kb로 확줄여졌지요.
그리고 lazyloading 또한 작동하죠 👏👏👏👏

결론

Image를 사용할때 우선 아이콘라면 Svg, 이미지라면 webp || MozJPEG && Pngquant를 사용할 예정이다. lazysize를 이용하여 vw별로 감량된 사이즈의 좋은 퀄리티의 이미지를 제공하려고 노력 해보자, lazysizes 를 좀더 사용해 봐야할 것 같습니다 🔥

profile
Basic in the end👻

1개의 댓글

comment-user-thumbnail
2019년 10월 24일

한번 사용해볼게요. 감사합니다. :)

답글 달기