본문 바로가기

Web Performance Optimization

[WPO] 이미지 사이즈 최적화 : WEBP

이미지 포맷 크기 : PNG > JPG > WEBP

 

📌 WEBP

  • 구글에서 나옴, 지원하지 않는 브라우저가 꽤 있음
  • 하지만 화질, 용량을 따져봤을 때 JPG보다 좋은 면이 있어서 사용하려는 움직임이 있음!
  • 이것을 이용해서 이미지 사이즈를 최적화 해볼것!

📌 Squoosh.app

  • 구글에서 출시
  • WEBP를 위한 서비스

사이즈도 줄이고, WebP로 확장자 재설정

 

 

 

 

 


 

홈페이지에 적용해보기

- squoosh를 이용하여 이미지를 webp 확장자로 변경한 뒤, import!

 

 

하지만, 앞서 언급했듯이 webp를 지원하지 않는 브라우저가 있다.

이럴 경우, 맨 처음에 webp를 지원하는 브라우저인지 판단하는 작업이 필요하다 

<picture /> 태그 이용!

 

 

📌 <picture />

예제 1)

<picture>
    <source srcset="/media/cc0-images/surfer-240-200.jpg"
            media="(min-width: 800px)">
    <img src="/media/cc0-images/painted-hand-298-332.jpg" alt="" />
</picture>

 

<source> : 내가 어떤 환경에서 특정 이미지를 사용하겠다를 명시하기 위한 태그, 여기서는 사이즈에 따라 로드할 이미지가 달라지고 있음

<img> : 이미지의 원본

 

예제 2) 

- 우리가 사용할 예제

- 확장자에 대한 분기

<picture>
  <source srcset="photo.webp" type="image/webp" />
  <img src="photo.jpg" alt="photo" />
</picture>

type 속성을 통해 webp라는 확장자가 현재 브라우저에서 사용가능 한지 확인 → 가능하면 webp이미지 로딩

불가능 하다면 <img> 의 jpg 이미지 로딩

 

 

예제 2번 적용해보기

<picture>
    <source data-srcset={props.webp} type= "image/webp"/>
    <img data-src={props.image} ref={imgRef}/>
</picture>

 

 

지난 포스팅에서 알아봤던 이미지 Lazy 로딩 적용해보기

function Card(props) {

	const imgRef = useRef(null);
	
	// 이미지는 최초 한번만 로드되면 되니까
	useEffect (() => {
		const obtions = {};
		const callback = (entries, observer) => {
			entries.forEach(entry => {
				if (entry.isIntersecting) {
					const target = entry.target
					const previousSibling = target.previousSibling

					target.src = target.dataset.src
					previousSibling.srcset = previousSibling.dataset.srcset;
					observer.unobserve(entry.target)
				}
			});
		} 
		const observer = new IntersectionObserver(callback, obtions);
		observer.observe(imgRef.current)
	}, [])
	 
	return (
		<div className="Card text-center" >
			<picture>
				<source data-srcset={props.webp} type= "image/webp"/>
				<img data-src={props.image} ref={imgRef}/>
			</picture>
			<div className="p-5 font-semibold text-gray-700 text-xl md:text-lg lg:text-xl keep-all">
				{props.children}
			</div>
		</div>
	)
}

entry.target.previousSibling : img의 이전 element인 <source/>가 선택됨

srcset → data-srcset

 

 

🚀 구현 홈페이지 Network 탭

webp 확장자 파일이 로드됨을 확인!

 

 


Reference

Inflearn : 프론트엔드 개발자를 위한, 실전 웹 성능 최적화(feat. React)