이전에 Next.js Image 컴포넌트가 어떻게 동작하는지 설명했습니다. 이번에는 Next.js 이미지 컴포넌트를 가지고 어떻게 이미지 최적화를 시도했는지 설명드리도록 하겠습니다. 설명에 앞서서 제가 한 방식이 옳은 방식인지 아직 모르겠으며 시도하고 있는 과정 중에 있음을 말씀드립니다.

첫 번째 시도: Next.js Image 컴포넌트 사용하기

Next.js 에서 기본적으로 제공하고 있는 이미지 최적화 기술에는 이미지 파일 크기 최적화, CLS 방지, lazy loading, 이미지 크기 최적화 가 있습니다. 이 글에서는 적용기~~(라 쓰고 분투기라 읽는다)~~를 위주로 소개해드리고자 하므로 각각의 자세한 설명은 공식 홈페이지 또는 다른 블로그를 참고하시기를 바랍니다.

간단하게만 설명을 드리자면, 다음과 같습니다.

Untitled

문제점 - docker 배포로 인한 캐시 리셋

Next.js 의 이미지 캐시는 on-Demand 로 동작합니다. 즉, 이미지 리소스 요청 시점에 캐시를 만들게 되는데 해당 캐시 파일은 <**distDir**>/cache/images 하위에 저장이 됩니다. (저의 경우는 .next/cache/images 하위에 저장이 되었습니다.)

이 시점에서 문제가 발생하게 됩니다. 제가 다니는 회사에서는 Next.js SSR 서비스를 쉽게 관리하기 위해서 docker 를 사용하고 있는데, 새로 빌드를 하게 되면 새로운 docker 이미지가 만들어지면서 이전에 있던 빌드 파일이 모두 사라지게 되었습니다.

해결을 위해서는 docker 이미지가 교체되어도 <distDir>/cache 폴더가 남아있도록 개발해야만 했습니다.

두 번째 시도: S3 에 캐시 저장하기

제가 여기서부터 잘못 해결한 것 같다는 생각이 듭니다. 쓸데없는 삽질을 더 보고 싶지 않으시다면 아래로 이동해주세요. Docker setting 을 제대로 했다면 두 번째 시도부터는 하지 않아도 됐을 것 같습니다.. (아직 확실치는 않음)

docker 이미지가 교체돼도 /cache 폴더를 남아있게 하기 위해서 SRE 파트 팀원 분과 협업을 진행했습니다. 처음 제안주신 방법은 기존 docker 이미지를 새로운 이미지로 교체하기 전에 S3에 cache 파일을 업로드한 후, 교체 후 이미지를 실행시키기 이전에 다시 S3 에 있던 데이터를 저장하는 방식 이었습니다.

- name: Save Image cache
  run: |
    POD=`kubectl get pods --no-headers -o custom-columns=":metadata.name" | grep [저장할 폴더명]`
    kubectl cp $POD:/app/.next/cache/images/ ./images -c [저장할 폴더명]

- name: Copy image cache to webview container
  run: |
    POD=`kubectl get pods --no-headers -o custom-columns=":metadata.name" | grep [저장할 폴더명]`
    kubectl cp images $POD:/app/.next/cache/ -c [저장할 폴더명]
    kubectl exec  $POD -c [저장할 폴더명] -- ls /app/.next/cache/images

CI/CD 쪽을 직접 세팅하지는 않아서 자세한 사항은 모르지만 이미지를 교체하기 전에 hook 같은 것을 이용해서 해당 작업을 진행했습니다.

문제점 - 100% 캐싱하는 것이 불가능