요즘 신규 프로젝트에 들어가기 앞서 기존 프로젝트를 개선하는 작업을 하고 있다. 렌더링 속도가 너무 느려서 lighthouse로 페이지를 하나씩 짚어보고 있는중이다.
분석을 하다보니 아래와 같이 이미지 사이즈 지정을 해주지 않아 5.57s라는 긴 시간이 걸리고 있음을 알게되었다. lighthouse에서 제안해주는대로 next의 Image 태그에 size를 지정해주기로 했고 자세히 알아보게 되었다.
Nextjs 공식문서에서 size에 대한 설명을 볼 수 있었다. 이렇게 사이즈를 미리 지정해주면, 브라우저에서 이미지를 다운로드할때 정해진 크기로 다운받을 수 있다. 그렇지 않으면 스크린 사이즈에 맞추기 때문에 100vw만큼 커질 수도 있다.
기존에는 기본 태그인 img를 쓰고 있었기 때문에 Image 태그로 교체해주었고 sizes를 추가해주었다.
이슈: 이미지 에러에 대한 처리
그렇게 size를 지정해주고 끝날 줄 알았는데 이슈가 발생했다 ㅎㅎ 기존 이미지중엔 서버에서 받아오는 이미지도 있었는데 서버 에러로 뜨지 않는 것들이 있었다. 그래서 img 태그의 onError property를 통해 뜨지 않는 이미지에는 디폴트 이미지를 넣어주고 있었다.
그런데 Image 태그로 교체해주고나니 디폴트 이미지가 뜨지않았다. 개발자 도구의 element 탭을 확인했는데 img 태그의 src에는 디폴트 이미지가 제대로 들어가 있었다. 콘솔을 확인해봤더니 서버의 이미지를 읽어오지 못한다는 403 Forbidden error가 멈추지 않고 쌓이고 있었다. 이미지를 다시 확인해봤더니 srcset에 기존의 에러이미지가 들어있었다.
이에 대해 더 찾아봤더니 srcset은 next image에서 size를 지정해주면 그거에 맞춰서 이미지를 받아와 저장해두는 곳이라고 한다. 위의 공식 문서에서 size를 지정해두면 image source set이라는 곳에 저장해둔다고 했는데 그게 이부분이었나보다.
이것에 관여하는 unoptimized를 true로 설정하면 에러가 더이상 나진 않겠지만 그럼 의미가 없다고 생각했다. 그런데 마침 코드에 이미지의 에러가 났을 때 추적할 수 있는 state가 선언되어있는 걸 보았고 이를 활용하게 되었다. 그래서 unoptimized에 해당 state를 넣어서 해결해주었다.
그렇다면 왜 계속해서 에러가 쌓이고 있었을까? chatGPT에 질문을 해보았다. next/image에서는 가장 최신의 이미지 버전을 가져오는데 revalidate는 옵션을 통해 그 시간을 조절할 수 있다고 한다. 기본으로 지정된 시간만큼 계속해서 최신 버전을 가져오려고 시도했고 그만큼 에러가 쌓이고 있었던 것이다.
에러가 나는건 언제나 당황스럽지만 해결하면서 많은 것을 알게 되어 좋았다.