밝을희 클태

[ Next.js] Image태그의 sizes 본문

NextJS

[ Next.js] Image태그의 sizes

huipark 2024. 6. 12. 14:31

환경

Next.JS 14 APP route

 

지금 진행 중인 프로젝트가 있는데 Next.js로 하고 있다. 해당 프레임워크를 사용하는 이유 중 하나가 Image 최적화 때문인데 중고거래 사이트에서 가장 중요한 건 많은 양의 이미지를 다루는 만큼 Image 최적화가 중요하다 생각이 들어 Next.js를 골랐다.

 

Next.js에서 어떻게 이미지를 최적화할 수 있을까?

sizes

 이미지의 크기를 설정할 때 width, height를 줄 수 있는데 이미지를 반응형으로 만들기 위해서는 해당 props를 사용할 수 없다. 그러면 fill을 사용해야 하는데 fill은 이미지를 부모의 크기를 기반으로 생성이 된다. 

fill을 사용하기 위해서는 부모는 반드시 relative 속성을 줘야 함

 부모의 크기를 채우기 위해서는 페이지가 로드될 때 이미지를 얼마만큼의 크기로 가져와서 렌더링 해줄지 알려주는 게 바로 sizes props다. 따로 지정을 해주지 않으면 뷰포트의 전체 크기(100vw)로 이미지를 가져와서 부모 요소의 크기에 맞게 이미지를 넣어준다. 

 

 문제는 만약 부모의 크기가 뷰포트의 20vw를 차지하고 있고 자식의 Image태그에 따로 sizes를 지정해주지 않으면 이미지의 사이즈를 20vw정도로 가져오면 되는데 100vw 만큼의 사이즈로 가져와 성능에 문제가 생길 수 있다.

 

이미지를 fill로 설정할 경우, Next.js가 자동으로 적절한 srcset을 생성하여 사용한다.

deviceSizes는 이미지에 따로 sizes를 적용해주지 않았을 경우 srcset이고

imageSizes는 sizes를 적용할 경우 해당 size만큼 추가로 srcset이 생성이 된다.

    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],

 

sizes가 20vw이고 뷰포트의 크기가 1000px 일때 1vw는 10px이 된다.

이미지를 렌더링 할 때 필요한 사이즈는 10 * 20vw(sizes) = 200px이 된다.

srcset에 200w는 없기 때문에 한 사이즈 바로 위인 256w 사이즈를 요청하게 된다

<Image
      src={img.path}
      alt={img.name}
      // sizes="(max-width: 690px) 128px, (max-width: 1280px) 20vw, 235px"
      sizes="20vw"
      fill
      className="rounded-sm"
/>

그런데 확인한 결과 384w의 사이즈를 요청했다.

브라우저에서 꼭 바로 한단 계위의 srcset을 선택하지 않는다. 디스플레이의 해상도 등 다양한 환경을 고려하여 srcset을 선택한다.

최종적으로 내 프로젝트에 sizes는 아래와 같이 주었다.

<Image
  src={img.path}
  alt={img.name}
  sizes="(max-width: 690px) 128px, (max-width: 1280px) 20vw, 235px"
  fill
  className="rounded-sm"
/>

이미지의 최대 크기는 234.4px이며, 뷰포트가 1280px 이하일 때는 20vw, 690px 이하일 때는 128px 크기의 이미지를 요청한다.

srcset

지금 srcset을 보면  3840만큼의 srcset이 만들어져 있다. 내 프로젝트의 최대 넓이는 1280px인데 그 이상의 srcset은 불필요하다. srcset을 생성할 때도 리소스를 사용하기 때문에 next.configs의 파일에 해당 내용을 추가해 최대 srcset을 1200까지 만들게 했다.

images: {
    deviceSizes: [640, 750, 828, 1080, 1200],
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },

이 설정을 통해 필요 이상의 크기의 이미지를 로드하는 것을 방지하여 리소스 사용을 최적화하고, 페이지의 로딩 시간을 개선할 수 있다