Project/foliohub

[Next.js] 이미지 next/image 적용해보기

솔B 2024. 4. 12. 01:36

오늘은 Next.js에서 이미지를 사용하는 방법에 대해서 알아보겠다.

이 글은 Next.js 14를 기준으로 작성되었다.

이미지 최적화 전략

이미지를 최적화하기 위한 전략에는 아래와 같이 다양한 방법이 있다.

  • png, jpeg 형식보다는 webp, avif 형식의 이미지 파일 사용하기
  • 이미지 Lazy Loading 처리하기
  • 디바이스 크기에 알맞은 이미지 크기로 리사이징
  • 이미지 캐싱하기

이러한 작업을 Next.js에서 해주고 있는데 어떻게 적용할 수 있는지 알아보겠다!

1. webp로 변환

next/image는 png, jpeg 등 형식을 webp로 변환해 이미지 용량을 줄여준다.

webp보다 2019년에 만들어진 avif가 여러 형식(jpeg, webp) 보다 훨씬 더 좋은 무손실 압축과 고품질을 자랑한다.(webp보다 인코딩하는데 20%는 더 오래 걸리지만 20% 더 작게 압축된다고 한다) 하지만 avif는 지원하지 않는 브라우저가 있을 수 있다. 

 

얼마나 효과가 있는지 하나씩 적용을 해봤는데 webp와 avif가 확실히 기존 형식에 비해 size가 줄어든 것을 확인할 수 있었다. 나의 경우 avif는 큰 효과를 모르겠어서 webp로 사용했다. 

일반 img 태그 사용 시 

next/image 적용해 webp 사용 시

avif 사용 시

 

2. 이미지 Lazy Loading 처리

Lazy Loading이란 웹 페이지 성능을 향상시키기 위한 기술 중 하나로, 페이지가 로드될 때 이미지를 한 번에 다운로드하는 대신 페이지가 스크롤될 때 필요한 이미지만 로드하는 방식을 의미한다.

과거에는 Intersection observer 또는 scroll 이벤트를 활용하여 이미지를 동적으로 로드했다. 최근에는 img 태그에 loading 속성을 사용해 Lazy Loading을 적용할 수 있다고 한다.

 

이런 기능도 Next.js에서 지원해주고 있다. 기본적으로 next/image를 사용하면 Lazy loading이 적용되고 이를 끄고 싶다면 priorty 속성을 true로 설정해 주면 된다. 또는 loading="eager"로 설정할 경우에도 이미지를 즉시 로딩하지만 성능을 저하시킬 수 있다고 한다.

 

나의 경우 우선순위가 높은 이미지(페이지를 로드했을 때 화면에 바로 보이는 이미지)는 priority를 true로 적용해 줬고 스크롤되면서 필요한 이미지들은 기본값으로 두었다.

priority

기본값은 false이고, priority를 true로 설정하면 높은 우선순위로 간주되어 preload된다. LCP(Largest Contentful Paint, 웹 페이지가 로드되는 동안 사용자에게 가장 먼저 보이는 콘텐츠 요소로 웹 페이지 성능 및 사용자 경험을 평가하는데 중요한 지표 중 하나) 요소는 priority를 true로 적용하는 것이 좋다.

 

3. 디바이스 크기에 알맞는 이미지로 리사이징

모바일 화면에서 pc에서 사용되는 큰 이미지를 사용하는 것은 낭비이다. 따라서 각 화면에 알맞은 이미지 크기를 보여주는 것이 성능을 최적화하는데 도움이 된다. 

Image 태그에서 width와 height를 명시할 경우 그에 맞게 생성된다. fill을 사용할 경우 아래처럼 자동으로 srcset이 지정되어 디바이스 별 이미지 사이즈를 설정해 준다.

(좀 과하게...? 디바이스별 이미지 사이즈를 만들어주는 게 아닌가 하는 생각이 들어 이 부분에 대해서는 좀 더 찾아봐야 할 거 같다..! next.config.js에서 설정해 주는 값도 무엇을 기준으로 deviceSizes와 imageSizes를 설정해줘야 하는지 등도 의문이다 )

이걸 next.config.js에서 원하는 값으로 설정할 수 있는데

만약 원하는 디바이스 중단점과 그에 따른 이미지 넓이가 있다면 next.config.js 파일에 아래처럼 작성해 주면 된다. 이런 값을 별도 설정하지 않는다면 아래의 기본값이 사용된다.

module.exports = {
  images: {
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
}

 

4. 이미지 캐싱

.next/cache/images안에 이미지를 자동으로 캐싱하도록 지원한다. vercel에 배포할 경우 최대 31일까지 저장해둔다고 한다.

X-Nextjs-Cache를 보면 캐싱 상태를 확인할 수 있다.

MISS : 경로에 캐시가 없음

STALE: 경로가 캐시에 있지만 재확인 시간을 초과했으므로 백그라운드에서 업데이트됨

HIT: 경로가 캐시에 있고 재확인시간을 초과하지 않음

 

나의 경우 이미지를 이전에 한번 불러온 상태라서 캐시 되어있는 이미지가 사용되었음을 알 수 있다.

 

이외에도 Next.js에서 Image는 다양한 기능을 가지고 있고 오늘은 내가 사용한 기능들을 위주로 작성해 봤다.

최적화된 이미지 사용은 웹 페이지 성능 향상과 함께 사용자에게 더 좋은 경험을 줄 수 있으므로 중요하다. 앞으로도 추가적인 기능을 사용하게 되면 추가적으로 더 작성해 보겠다! 👋

 

참고자료

 

Components: <Image> | Next.js

Optimize Images in your Next.js Application using the built-in `next/image` Component.

nextjs.org

 

 

이미지 최적화를 위한 전략 feat.Nextjs

이미지 최적화를 위한 다양한 전략을 알아봅시다. 나아가 nextjs에선 어떻게 이미지를 최적화할 수 있을까요?

velog.io

 

+ Lighthouse의 Performance가 개선되었다!!

이전 Next.js의 next/image를 적용하기 전이고

 

적용한 후 !!

적용하기 전에 정확히 분석을 안 해봐서 상관관계가 있는지 100% 확신은 안드지만 눈에 보이는 속도부터 빨라졌담!! ✨ ✨ 

신기하네... 🤔