블로그 제작기 - 이미지 관리하기

2025년 04월 16일

블로그 제작기이미지 관리Next.js
블로그 제작기 - 이미지 관리하기

이미지 관리에 대한 고찰

블로그 서비스를 만드는 것이라면 가장 골치아픈 부분이 이미지 관리일 것이라고 확신한다. 나만의 작은 블로그 일 뿐이지만, 장기적인 관점으로 보았을 때 이미지를 효율적으로 관리하는 체계를 만드는 것은 필수였다. 용량이 큰 이미지, 사이즈가 다른 이미지 들을 어떻게 처리할 것인지 아직도 난감하게만 느껴진다.

예를 들어 작은 사이즈의 이미지를 본문에 넣었을 때, 이미지를 억지로 블로그의 사이즈에 맞춰서 늘리게 되면 이미지가 깨지면서 가독성이 저해된다. 이걸 단순하게 포스팅한 유저 혹은 내가 적절한 이미지를 고르는게 맞는건지 아니면 클라이언트단에서 처리해줄 방법이 없는지 여전히 고민이 되고 있다. 여러 블로그 서비스를 참고해 보면 유저가 적절한 이미지를 고르게 하는 것이 맞는 것으로 보이지만, 혹시나 다른 방법이 없나 고민 중이다.

용량이 큰 이미지도 문제다. 특히나 작은 규모의 블로그로써는 치명적이었다. 대략 20MB가 넘어가면 사실상 최악에 가까운 렌더링 속도가 나온다. 라이트하우스의 점수도 80~90점대를 웃돌다가 20점대로 확 떨어진다. 객관적인 지표점수도 떨어지고 UX도 떨어지는 이 현상을 어떻게 해야 최적화를 할 수 있을지 고민이다. 마크다운으로 페이지를 렌더링 하다보니 img태그로 전환이 되어서 Next에서 지원하는 Image 최적화 기능을 사용하기가 어려운데 어떻게 해야 대체할 수 있을지 다음편에서 서술해보려고 한다. 혹은, 이 방법이 별로 효과적이지 못하다면 다른 라이브러리의 활용을 고민해봐야 할 것 같다.

이미지 저장방식은 캐싱 & 중복저장 방지

이걸 구현하게 된 것도 블로그의 글을 계속 쓰다보니 깨닫게 된 사실이다. 재사용된 이미지가 계속해서 중복으로 저장되어져 왔고 이와 관련된 대책이 전혀 없었던 것이다. 그래서 아직 이미지 최적화는 덜 되었지만 저장 및 관리 방식은 급하다고 판단이 돼서 나름의 방식을 구현해 보았다.

1. 이미지 저장 방식

현재 블로그의 이미지 저장 방식은 Supabase Storage에 저장하도록 구축되어 있다.

  • blog-images 라는 버킷에 저장
  • 블로그에 사용되었던 이미지를 구분하기 위해서 날짜별 폴더를 형성
  • 이미지를 해시 기반 파일명으로 저장해서 중복 방지
  • 해시 기반 캐싱으로 중복 업로드를 최소화

uploadImageToStorage

2. 이미지 처리 워크 플로우

마크다운 내 이미지를 처리하는 방식은 다음과 같다.

  • 마크다운 파일 내의 이미지 삽입 패턴으로 이미지 인식
  • 로컬 경로 확인 및 이미지 파일 읽기
  • 이미지 해시 생성 및 중복 확인
  • Supabase Storage에 업로드
  • 마크다운 내 이미지 URL을 Supabase URL로 교체

uploadContentImages

3. 썸네일 이미지 처리

썸네일 이미지는 본문에 사용되는 이미지와 별도로 관리한다.

  • 기존 썸네일과의 해시 비교로 변경 여부 확인
  • 썸네일이 변경된 경우 기존 썸네일 삭제(Storage)
  • 새로운 썸네일을 thumbnails 폴더에 업로드
  • 업로드된 썸네일 URL 반환

uploadThumbnail

4. 사용되지 않는 이미지 처리

본문 내의 이미지가 수정되어서 더 이상 사용되고 있지 않다면 이미지를 삭제하도록 로직을 구성했다.

  • 기존 마크다운과 새 마크다운에서 이미지 URL 추출
  • 더 이상 사용되지 않는 URL 목록 생성
  • 해당 이미지들을 Supabase Storage에서 삭제

cleanupUnusedImages, deleteImagesByUrls

5. 오류 처리 및 재시도 설정

CI 파이프라인에서 가끔 이미지 업로드나 삭제를 할 때, 실패를 하는 경우가 있었다. 아마도 일시적 오류나 네트워크 오류일 가능성으로 판단돼서 별도의 retry함수를 만들어서 안정적으로 업로드를 시도하도록 하고, 디버깅 로그를 남기게 해서 원인을 알 수 있도록 구성했다.

  • 최대 3회 재시도 설정, 실패시 반복 시도
  • 각 횟수 사이에 대기시간 적용 (1000ms)
  • 실패시 원인과 남은 재시도 횟수 표기
  • 모든 재시도가 실패하면 최종 오류 발생

retry

결론

결론적으로, 이미지 관리 시스템은 나름대로 체계적으로 구현했다고 생각한다. Supabase Storage를 활용해 클라우드에 이미지를 저장하고, 해시 기반으로 파일명을 관리하며, 캐싱 시스템으로 중복 업로드를 방지하고 있다. 특히 더 이상 사용하지 않는 이미지를 자동으로 정리하는 기능은 블로그 관리 측면에서 꽤 만족스럽다.

하지만 여전히 아쉬운 점이 있다. 썸네일 이미지는 Next.js의 <Image> 컴포넌트를 통해 최적화되어 있지만, 마크다운 본문 내 이미지는 아직 그렇지 못하다. 서론에서 언급했던 것처럼 용량이 큰 이미지와 사이즈가 다른 이미지들의 문제는 여전히 해결해야 할 과제로 남아있다.

다음 글에서는 마크다운 내 이미지를 Next.js의 <Image> 컴포넌트로 대체하는 방법을 모색해보거나, 이 방법이 효과적이지 않다면 다른 라이브러리 활용한 방식에 대해서 작성해보려고 한다. 궁극적인 목표는 이미지로 인한 성능 저하 없이 깔끔한 블로그 운영을 하는 것이니까!!! 🔥