next.js의 image의 기초 특징에 대해 알아보자.
맨 처음에는 <img>
태그로 코드를 작성하고 react의 기본 useState
로 로스트아크 예시 이미지 리스트를 구현했다.
별 생각이 없었는데 터미널의 수많은 경고창들을 보고 내가 next.js를 잘 모르고 썼구나 생각이 들었고 이것이 스터디의 계기가 되었다.
⚠ For production Image Optimization with Next.js, the optional 'sharp' package is strongly recommended. Run 'npm i sharp', and Next.js will use it automatically for Image Optimization.
위 경고의 이유인 즉슨 next.js는 자동으로 이미지 최적화를 위해 sharp
라는 라이브러리를 사용하기 때문에 이를 미리 install해두는 것을 추천한다고 한다.
npm install sharp
sharp
는 노드 진영의 이미지 리사이징 라이브러리다.
node v10 이상이 요구되며, OS를 타기 때문에 리눅스 환경에서 못 찾는 경우가 있다고 한다.
51:9 Warning: Using
<img>
could result in slower LCP and higher bandwidth. Consider using<Image />
fromnext/image
to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
하지만 <img>
를 사용하는 것은 문제가 있어 보인다.
경고의 지침에 따라 <Image />
컴포넌트를 사용해보자.
<Image
src={`${process.env.NEXT_PUBLIC_CLOUDINARY_BASE_URL}/${item.version}/${item.public_id}.${item.format}`}
alt={item.original_filename}
width={300}
height={300}
className="object-cover rounded-lg"
/>
Image 컴포넌트는 width
, height
, alt
, src
속성을 필수로 요구한다.
다만 public 폴더와 같은 정적 이미지들을 불러오는 경우나 13버전부터 사용되는 boolean fill
속성을 쓰는 경우 width
, height
가 생략될 수 있다.
fill
속성을 사용한다면 자동으로 부모 영역을 채운다고 한다. 실제로 어떻게 다르냐면,
without fill
with fill
포트폴리오 탭 밑에 있어야 할 이미지가 absolute처럼 상단에 고정된다.
img 요소에 position: "absolute"가 자동으로 지정되기 때문에 부모 요소에 position: "relative", position: "fixed", 또는 position: "absolute" 를 지정해야 합니다.
출처 https://velog.io/@qhflrnfl4324/nextimage-반응형-적용하기-Next.js-13
Image with src "/images/profile.png" has legacy prop "layout". Did you forget to run the codemod?
Read more: https://nextjs.org/docs/messages/next-image-upgrade-to-13
next.js가 13버전에 들어오면서 기존의 layout
속성도 사라졌다. 만약에 꼭 layout="responsive"
등의 속성 처리를 원한다면 codemod를 next/lagacy/image
로 바꾸어야 한다. (13 이전의 변화들이 legacy로 이전했다)
npx @next/codemod next-image-to-legacy-image .
warn-once.js:16 Image with src "/images/profile.png" was detected as the Largest Contentful Paint (LCP). Please add the "priority" property if this image is above the fold.
Read more: https://nextjs.org/docs/api-reference/next/image#priority
priority 속성은 lazy loading 여부를 지정한다.
profile.png 이미지가 LCP에 해당하기 때문에 priority
가 true
로 설정되어야 한다는 경고이다.
해당 속성이 지정되지 않은 경우 기본값을 false
로 설정된다.
페이지가 로딩하는 성능을 측정하는 지표이다. 페이지 로드를 시작한 시점을 기준으로 잡아서 뷰포트 내의 가장 큰 이미지, 혹은 텍스트 블록의 렌더링 시간을 보고한다.
2.5초가 우수한 ui 제공이라고 합니다.
<Image
src="/images/profile.png"
alt="profile"
width={400}
height={400}
className="rounded"
priority={true} //추가되어야 한다
/>
나는 단순히 warning을 해결하는 것에 그쳤지만 next.js 공식 git에서 sharp를 불러오는 부분부터 거슬러 올라가 자세하게 정리한 올리브영 테크 블로그가 가장 인상 깊었다.
이미지를 최적화한다는 것은 여러 방법이 있다.
단순히 어떤 라이브러리를 사용해야 한다에 그치지 말고 이론만 알았던 캐시의 개념도 되짚어 보고, 라이브러리들 간의 성능도 누가 더 나은가 등의 생각할 거리를 계속 늘려나가야 한다.
next.js는 모든 이미지 최적화를 다 해주나? 그런 것은 아니다. (답은 아래 기술 블로그에)
이런 것들을 질문하고 답을 찾아나가는 것이 필요하다는 걸 깨달았다.
https://oliveyoung.tech/blog/2023-06-09/nextjs-image-optimization/
그 외에도 다양한 블로그 경험들을 읽은 것이 도움이 되었다.
카카오 엔터테인먼트의 이미지 최적화
맨 처음 sharp 설치부터 layout shift 개념부터 이를 어떻게 해결했는지의 과정이 잘 설명되었다. blur등의 코드 예제가 잘 나와있다.