Next.js

Next Image 똑똑하게 사용하기(feat. Vercel Deploy)

Kir93 2022. 10. 24. 18:56
728x90
반응형

1. 개요

웹 사이트를 제작할 때 로딩 속도와 퀄리티에 있어 가장 중요한 부분은 이미지라고 생각합니다.

너무 낮은 화질의 이미지를 사용할 경우 로딩 속도는 빨리질 수 있지만 사이트의 전체적인 퀄리티는 무척 낮아 보이는 문제가 발생하며, 이미지가 너무 높을 경우 이미지를 로딩하는데 긴 시간이 걸려 레이아웃 쉬프트가 발생하거나 사이트의 전체적인 로딩이 늦어질 수 있습니다.

 

그렇기 때문에 웹 사이트를 제작한 뒤 최적화를 진행할 때 가장 먼저 진행해야 되는 부분이 이미지를 최적하는 것이라고 생각합니다.

이번 글에서는 Next를 사용하는 데 있어 제가 이미지를 최적화하는 방법에 대해 소개하겠습니다.

2. Web에서 주로 사용하는 이미지 형식

  1. JPEG : 가장 널리 사용하는 파일 형식으로 거의 모든 브라우저에서 지원하지만 이미지의 품질 저하가 심하다는 단점이 존재합니다.
  2. PNG : 무손실 압축을 지원하는 파일 형식으로 고화질의 이미지가 필요한 경우 많이 사용하며 거의 모든 브라우저에서 지원하지만 용량이 상대적으로 크다는 단점이 존재합니다.
  3. WEBP : jpg를 대체하기 위해 제시된 형식으로 jpg보다 화질 저하를 최소화하면서 파일 크기를 축소한 포맷으로 대부분의 브라우저에서 지원하지만 버전에 따라 지원하지 않는 버전도 존재합니다.
  4. AVIF : 가장 최신의 포맷으로 가장 좋은 압축 기능을 제공하며 더 높은 색 깊이, 투명도 등을 지원하지만 크롬, 오페라, 삼성 브라우저의 최신 버전에서만 지원하고 있습니다.(현재는 ios16 버전의 safari에서 지원을 시작했습니다.)

웹 사이트를 제작할 때 가장 많이 사용하는 이미지 형식들은 위와 같은데 설명만 들었을 때는 avif 형식을 사용하는 것이 가장 좋아 보이고 좋은 선택으로 보입니다.

 

하지만 사용자가 접속하는 브라우저의 환경은 천차만별이기 때문에 단순히 모든 이미지를 avif 형식으로 지정하기에는 리스크가 존재합니다.

 

그렇기 때문에 나온 것이 html의 picture태그입니다.

3. picture태그와 Next에서 사용하는 방법.

<picture>
  <source srcset="/img/test.avif" type="image/avif" />
  <source srcset="/img/test.webp" type="image/webp" />
  <img src="/img/test.jpg" alt="test image" width="360" height="240" />
</picture>

 

위와 같이 picture태그를 사용하면 이제 사용자의 접속 환경에 따라 avif, webp, jpg 순으로 지원 여부를 체크한 뒤 이미지를 표현해 줍니다.

 

하지만 모든 이미지를 이렇게 처리하기는 무척 귀찮은 작업이며 Component로 만든다고 하더라도 Static이미지마다 저렇게 3개의 이미지를 넣는 것은 프로젝트의 크기가 늘어나며 외부에서 가지고 오는 이미지의 경우 더욱더 가지고 오기 어렵다는 단점이 존재합니다.

 

그렇기 때문에 next에서는 간단하게 이미지의 형식을 변경하는 것을 지원합니다.

 

// next.config.js

...
module.exports = {
  ...
  images: {
    formats: ['image/avif', 'image/webp'],
  },
  ...
}

간단하게 위의 내용을 추가해 준다면 static이미지의 경우 바로 이미지의 형식을 변경한 내용을 제공해주며, 외부에서 가지고 오는 이미지 역시 Next를 만든 Vercel을 이용하면 바로 사용자가 지원하는 형식에 맞춘 이미지를 제공해 줍니다.

4. 이미지의 퀄리티 높이기

이제 이미지의 형식을 자동으로 변경할 수 있게 되었기 때문에 모두 만족스러울 수 있지만, Next의 이미지 태그에는 장점이지만 단점으로 보일 수 있는 요소가 존재합니다.

바로 이미지의 크기를 자동으로 resize 해서 가지고 온다는 점입니다.

 

이는 확실히 이미지의 로딩을 빠르게 하며 최적의 이미지를 가지고 온다는 장점이 존재합니다.

하지만 지금까지 경험했을 때, 대부분의 클라이언트의 경우 이미지의 화질이 낮아 보인다는 점을 지적합니다.

 

이때 제가 사용하는 작은 팁이 존재합니다.

이미지를 불러올 때 최소 2배의 크기로 설정하여 불러오는 것입니다.(저의 경우 주로 3배를 사용합니다.)

 

이는 위에서 설명했던 방식 중 속도 부분을 위배한 것 같지만, Next로 배포하면 자연스럽게 이미지 형식이 avif, webp형식으로 변경되기 때문에 더 적은 용량으로 더 좋은 결과물을 확인할 수 있습니다.

5. 이미지 업로드할 때 압축하기 (선택사항)

개인적으로는 그리 선호하지 않지만, 대용량의 사진 업로드가 많거나 다량의 이미지를 업로드해야 되는 사이트의 경우 이미지를 압축하여 업로드하는 방법을 이용하면 좋습니다.

 

제가 자주 사용하는 방법을 예로 들자면 해당 이미지를 사용하는 가장 큰 사이즈((반응형 웹의 경우 웹의 상세 페이지 x2), 퀄리티는 100%로 설정한 뒤 그 보다 큰 이미지의 경우에만 압축하는 형태를 주로 사용합니다.

 

그때 사용하는 라이브러리는 browser-image-compression으로 개인적으로 찾아봤던 라이브러리들 중 가장 인기도 많고 사용하기도 어렵지 않기 때문에 이 라이브러리를 추천합니다.

6. 이미지 캐싱하기

이제 마지막으로 이미지를 캐싱하는 방법에 대해 설명하겠습니다.

 

외부 이미지를 캐싱할 때 많이 사용하는 것은 cdn을 활용하는 것으로 큰 기업의 경우 자체 cdn서버를 운용하는 곳들도 있고 클라우드 플레어 등의 cdn서버를 이용하는 경우도 많습니다.

 

내부의 이미지의 경우 header의 cache-control을 이용해 max-age를 길게(주로 31536000(1년)을 많이 사용) 설정하는 방법을 많이 사용합니다.

 

하지만 위에서 설명했던 것처럼 Vercel배포를 사용한다면 이런 문제에서 벗어나 간편하게 모든 사항이 자동으로 캐싱되고 외부 이미지의 경우 vercel cdn에 저장되며 캐싱 처리됩니다.

 

물론 Next는 Vercel배포를 이용하지 않는 사람들을 위해 next.config.js를 통해 image cdn서버를 따로 설정하는 것과 같은 방법을 제공하기 때문에 주어진 상황에 맞춰 캐싱 전략을 효율적으로 구상하길 바랍니다.

 

반응형
반응형