✨ 참고 자료 출처
이미지 최적화를 이야기하기 위해서는 picture
와 source
태그 이야기가 빠질 수 없다.
퍼블리셔로 일할 때 은근 많이 사용했었던 태그들이다. 🤓 📚
반응형에 따라 이미지를 변화시키기에 유리하고, 최적화를 통한 성능 개선에도 도움을 준다.
picture
태그는source
태그를 이용한 반응형 이미지를 사용함으로써 대역폭을 절약하고 페이지 로드 시간 단축을 위한 목적으로 사용된다.❗️
picture
태그는 그 단어의 의미인 picture(사진)와는 직접적인 관계가 없다. 하나의img
태그에 대해 0개 이상의 반응형 이미지를 제공하는source
태그의 범위를 알려주는 컨테이너(부모 요소)라는 의미일 뿐이다.
source
태그는picture
태그 내에서 반응형 이미지 소스를 설정하는 요소를 뜻한다.
이제 아래 예시 코드를 보면서 이해해보자.
❗️코드펜 로고를 눌러서 큰 화면에서 직접 테스트해보는게 좋음!
<picture>
<!-- 최소 1280까지만 이 이미지를 보여주겠다는 의미 -->
<source media="(min-width: 1280px)" srcset="https://images.unsplash.com/photo-1536532184021-da5392b55da1?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8Ymx1ZSUyMHNreXxlbnwwfHwwfHx8MA%3D%3D&w=1000&q=80">
<!-- 최소 980까지만 이 이미지를 보여주겠다는 의미 -->
<source media="(min-width: 980px)" srcset="https://cdn.pixabay.com/photo/2017/08/06/08/55/key-chain-2590442_1280.jpg">
<!-- 모든 이미지를 불러오지 못했을 때 fallback으로 보여줌 -->
<img src="https://cdn.pixabay.com/photo/2022/09/02/19/55/crystal-7428278_1280.jpg" alt="대체 이미지가 여기 들어갑니다.">
</picture>
source
태그 안에 media
속성에는 미디어 쿼리를 넣어주면 된다.
내가 설정해준 미디어 쿼리에 따라 srcset
에 넣어준 이미지가 보여지게 된다.
위 예제처럼, 반응형에 따라 다양한 이미지가 보여질 수 있도록 설정해도 좋다.
혹은, 하나의 이미지 사이즈나 용량의 이미지를 넣어주어 알맞게 렌더링 될 수 있도록 해주면 된다.
img
태그는 있어도 되고, 없어도 된다.
단, 웹 접근성을 위해서 img태그를 반드시 넣어주는게 좋다.
또, img 태그는 fallback(source 이미지를 불러오지 못했을 경우 img태그를 대체해서 보여줌) 의 역할을 해주기 때문에 반드시 넣어주는 편이다.
webp는 구글에서 개발한 용량이 아주 작은 이미지를 뜻한다.
사진과 그래픽의 크기를 줄여 웹 사이트가 빠르게 로드되고 사용자에게 더 나은 경험을 제공한다고 한다.
588.87 KB의 이미지를 webp로 변환해 보았다.
44.33 KB로 용량이 확실하게 줄어든것이 확인된다!
webp로 변환해주는 사이트들이 많으니 이용해보면 좋을 것 같다.
✨ webp 로 변환하러 가기
갓스트 js에서는 이 모든 귀찮은 작업을 쉽게 가능하도록 해준다.
갓스트 Image는 기본 값으로 lazy loading을 제공한다.
뷰포트에 보여지는 이미지만 우선 보여주고 , 그 밖에있는 이미지들은 로딩을 지연시킨다.
불필요한 이미지 제외하고 필요한 이미지만 빠르게 로드하는 것!!
필요에 따라 사용하지 않도록 설정 가능함.
Image 컴포넌트를 사용했으면 반드시 너비와 높이를 지정해주어야 한다.
<Image
src='...'
alt='...'
width={276}
height={276}
/>
작은 사이즈의 이미지가 필요한데, 원본 사이즈는 어마어마하게 클 경우를 대비해서
너비와 높이를 미리 지정해두고 해당하는 사이즈로 변환된 이미지를 다운로드 한다.
또, 기본적으로 webp 이미지로 제공된다.
메인에서 일반 img 태그를 사용했었다.
<img src={banner.imageSrc} alt={banner.title} />
그럼 위 이미지에서 보이는 것 처럼 458KB 사이즈를 가진다.
import Image from 'next/image';
<Image src={banner.imageSrc} alt={banner.title} fill sizes='1195px' priority />
img태그 대신 next.js image 컴포넌트로 바꿔주면 어떻게 될까?
35.6KB의 webp로 자동 변환하여 이미지가 제공되고 있는 것을 확인할 수 있다!
fill
: 이미지를 감싸고있는 부모 요소의 너비와 높이를 가진다.
sizes
: 위 source
태그의 media
프로퍼티와 동일하다. 현재 내가 올린 코드는 분기점이 없이 하나의 px 사이즈만 들어가있는데, 이는 아직 디자인 반응형 분기 처리가 되어있지 않기 때문 (반응형 작업할 때 추가할 예정)
priority
: true 값을 넣어주면, 해당 이미지를 최우선적으로 preload(미리 로드)한다. 배너 이미지에 LCP 에러가 떴기 때문에 넣어주었다. (공식문서)
CLS(Cumulative Layout Shift) 즉, 레이아웃이 흔들리는 현상을 막아줄 수 있는 placeholder를 제공할 수 있다.
<Image
src='...'
alt='...'
width={276}
height={276}
placeholder='blur'
blurDataURL='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNcvHhTPQAGYgJ5cH4fHAAAAABJRU5ErkJggg=='
/>
빈 영역을 넣어줄 수도 있고 blur 속성을 사용해서 이미지를 넣어줄 수도 있다.
원본 이미지를 넣으면 당연히 안되고,
base64로 인코딩된 data url을 넣어주어야 한다.
아래 링크에서 손쉽게 컬러로만 이뤄진 픽셀 이미지를 생성할 수 있으니 해보시길!
✨ Base64 Encoded Pixel 생성하러 가기
placeholder가 적용되고
이미지가 적용되고 있는것을 확인할 수 있다.
역시 갓스트 ..
세상 각박한 개발 환경에 한줄기 빛..
📚 압도적 감사 (출처)
Next/Image를 활용한 이미지 최적화
Next.js 공식사이트
이미지를 최적화해서 좋은 기능이죠!
이 기능이 어떻게 만들어졌는지도 한번 알아보시면 더 재밌어요😁