이슈 내용
next/image 컴포넌트 및 sizes 속성을 부여하여 렌더링하는 이미지가 로드에 실패하는 현상이 발생했습니다. 모든 스크린 사이즈에서 실패하는 것은 아니고 몇 개의 특정한 사이즈에서만 생기는 이슈였습니다. 로드에 실패한 이미지를 크롬 개발자도구의 네트워크 탭을 확인해보면 아래와 같은 에러 메시지와 함께 400 에러가 뜨는 것을 확인할 수 있었습니다.
"w" parameter (width) of ${width} is not allowed
구글에 위의 에러메시지를 검색했을 때 검색 결과가 얼마 없었고, 크게 공론화된 이슈가 아니라는 것을 확인할 수 있었습니다. 경험적으로 봤을 때 이러한 경우는 원래 이슈가 문제라기보다는 설정값이 잘못되었다든지 엉뚱한 곳이 잘못된 경우가 대부분입니다.
next.config.js 및 이미지 최적화
Next.js는 next.config.js 파일에 설정된 deviceSizes와 imageSizes를 참조하여 이미지의 srcset 목록을 만들어 주는데요. 따로 설정을 하지 않으면 아래와 같은 기본값을 가집니다. 저는 디자인 시안에 적용된 미디어쿼리를 반영하고, 너무 많은 srcset이 생기는 것을 방지하기 위해 아래와 같이 커스텀 설정값을 적용했습니다.
// next.config.js
// 별도로 설정하지 않을시 Next.js가 제공하는 기본값
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
// 커스텀 설정값
images: {
deviceSizes: [375, 768, 1280, 1920],
imageSizes: [20, 32, 64, 128, 256]
},
앞에서 이 이슈는 몇 개의 특정 스크린 사이즈에서만 생긴다고 설명을 드렸는데요. 확인해보니 문제가 생기는 특정 스크린 사이즈는 제가 설정한 커스텀 설정값과 관련이 있었습니다.
이미지의 srcset 리스트 중에서 w=375, w=20 등 기본 값에는 없는 사이즈를 렌더링하려고 할 때만 문제가 생기는 것이었죠. 반면에 w=256과 같이 이미지의 크기가 기본 값에 포함된 것이라면 정상적으로 로드되는 것을 확인할 수 있었습니다.
더불어 해당 문제는 npm run dev나 소스코드 빌드 후에 npm run start 하여 실행하는 개발환경에서는 생기지 않는 문제였습니다. 오로지 배포 시에만 나타나는 문제였습니다.
이러한 이유 때문에 배포 환경이 의심되었고, 프로젝트의 배포 환경을 살펴보기 시작했습니다. 어떤 이유에서인지 "next.config.js의 설정값이 제대로 반영되지 않았을 것이다"는 가설을 세우고 문제에 접근했습니다.
문제는 배포 환경
해당 프로젝트는 AWS CodePipeline을 통해서 배포를 하고 있는데요. 코드 빌드 관련 설정은 biuldspec.yml 파일을 보면 됩니다. buidlspec.yml 파일을 살펴보니 artifacts의 files 리스트에 next.config.js가 포함되지 않은 것을 확인할 수 있었습니다. next.config.js를 추가한 후에 배포를 진행했습니다. 결과는 성공! 이미지가 커스텀으로 설정해준 deviceSizes, imageSizes 값에서 전부 정상적으로 렌더링되는 것을 확인할 수 있었습니다.
댓글