Skip to content

프로필 이미지 최적화 개선 (Next Image 업로드 전처리)

FE_juncci edited this page Mar 5, 2026 · 1 revision

📌 요약 (TL;DR)

문제

  • /me 페이지 LCP 후보 이미지가 1025×1024 PNG(약 944KB) 로 전달됨
  • 표시 크기(약 96~112px)에 비해 원본 크기가 과도
  • Lighthouse Improve image delivery 경고 발생
  • S3 캐시 정책이 없으면 반복 방문 시 매번 다운로드

해결

  • next/image 원격 이미지 최적화 경로 활성화
  • 프로필 업로드 시 256×256 WebP(quality 0.82) 로 전처리
  • LCP 이미지에 priority + fetchPriority="high" + loading="eager" 적용
  • /_next/image 경유 구조에서 불필요한 S3 preconnect 제거

결과

  • 이후 업로드되는 프로필 이미지 용량 대폭 감소
  • LCP 이미지 디스커버리 및 로드 우선순위 개선
  • 기존 대용량 이미지는 재업로드 또는 백필 전까지 유지

퍼포먼스 Metric 비교

Metric 개선 전 (추정) 개선 후 개선율
FCP ~0.8s 0.3s ⬆ 62% 개선
LCP ~2.5s 1.8s ⬆ 28% 개선
TBT ~50ms 0ms ⬆ 100% 개선
CLS ~0.08 0.017 ⬆ 79% 개선
Speed Index ~2.0s 1.0s ⬆ 50% 개선

이미지 전송 크기 비교

항목 개선 전 개선 후 절감
프로필 이미지 944 KB 13 KB ⬇ 98.6% 감소
추가 이미지 900KB+ 8 KB ⬇ 99% 감소
전체 이미지 요청 ~950KB ~30KB ⬇ 약 97% 감소

1) 📌 문제 배경

기존 /me 페이지에서는 next/image를 사용하고 있었지만, 실제로는 대용량 원본 이미지가 그대로 전달되는 상황이 발생하고 있었습니다.

대표적인 Lighthouse 경고

Improve image delivery
LCP request discovery
Use efficient cache lifetimes

문제의 핵심

작게 표시되는 프로필 이미지를
대용량 원본으로 전달하고 있음

예시

표시 크기 : 96px
원본 크기 : 1025px PNG
용량 : 약 944KB

2) 🎯 목표

1️⃣ LCP 후보 이미지의 다운로드 크기 감소

2️⃣ 새로 업로드되는 프로필 이미지를 일관된 규격으로 관리

3️⃣ Next.js 이미지 optimizer 파이프라인 정상 사용

4️⃣ 운영 환경에서 캐시 정책 적용 가능하도록 구조 정리


3) 🤔 설계 고민과 선택

고민 A) 표시 시점 최적화만 할 것인가 vs 업로드 시점도 줄일 것인가

선택지 비교

전략 특징
표시 시점 최적화만 Next optimizer 의존
업로드 시점 전처리 원본 자체를 줄임

표시 시점만 최적화하면

  • 런타임 환경
  • 배포 설정
  • optimizer 동작 여부

에 따라 효과 편차가 발생할 수 있음

선택

표시 시점 + 업로드 시점
이중 최적화
  • 표시 시점 → next/image
  • 업로드 시점 → 256px WebP 전처리

이유

  • 원본 자체를 작게 만들면 어떤 경로로 전달돼도 기본 비용이 낮음
  • 런타임 최적화 실패 시 최악 상황 방지

고민 B) LCP 이미지 lazy 유지 vs 우선 로드

선택지 비교

방식 특징
lazy 초기 로딩 지연 가능
eager 초기 네트워크 우선 로드

LCP 후보는 lazy일 경우

이미지 발견 → 로드 시작

순서가 늦어질 수 있음

선택

priority
fetchPriority="high"
loading="eager"

이유

  • 초기 HTML 단계에서 이미지 디스커버리 강화
  • 브라우저 스케줄러에 우선순위 신호 전달
  • LCP 지연 가능성 감소

고민 C) S3 preconnect 유지 vs 제거

기존 구조

이미지 요청 흐름

브라우저
   ↓
/_next/image
   ↓
Next 서버
   ↓
S3

즉 브라우저는 먼저 1st-party origin에 연결

문제

S3 preconnect → 실제 사용되지 않는 연결

Lighthouse

unused preconnect

선택

S3 preconnect 제거

이유

  • 실제 요청 흐름과 맞지 않는 힌트 제거
  • 불필요 네트워크 연결 방지

4) 🛠 구현 상세

4-1) Next Image 원격 최적화 경로 활성화

파일

next.config.mjs
images: {
  remotePatterns: [
    {
      protocol: 'https',
      hostname: 'refit-storage-prod.s3.ap-northeast-2.amazonaws.com',
      pathname: '/**',
    },
  ],
  formats: ['image/avif', 'image/webp'],
}

의도

  • S3 이미지를 Next optimizer가 처리하도록 허용
  • WebP / AVIF 변환 가능성 확보

4-2) /me LCP 이미지 우선순위 강화

파일

src/widgets/me/ui/MyPage.tsx
<Image
  src={user.profile_image_url ?? defaultUserImage}
  alt="프로필"
  width={112}
  height={112}
  priority
  fetchPriority="high"
  loading="eager"
  sizes="96px"
/>

효과

  • LCP 이미지 늦은 로딩 방지
  • 초기 렌더 단계에서 네트워크 우선순위 확보

4-3) 업로드 시 이미지 전처리

파일

useMyPageEditProfileImage.client.ts
const processed = await processImageFile(file, {
  maxWidth: 256,
  maxHeight: 256,
  mimeType: 'image/webp',
  quality: 0.82,
});

normalizedFile = processed.size <= file.size ? processed : file;

의도

  • 업로드 시 이미지 크기 표준화
  • 변환 실패 시 fallback
  • 변환 후 오히려 커지면 원본 유지

4-4) 편집 화면 preview 처리

파일

MyPageEdit.tsx
<Image
  src={profileImagePreview ?? profileImageUrl ?? defaultUserImage}
  alt="프로필 이미지"
  width={80}
  height={80}
  unoptimized={!!profileImagePreview}
  sizes="80px"
/>

의도

  • blob preview는 optimizer 대상이 아님
  • 원격 URL은 optimizer 경로 유지

4-5) 불필요 preconnect 제거

파일

layout.tsx
// removed
<link rel="preconnect" href="https://refit-storage-prod.s3.ap-northeast-2.amazonaws.com" />
<link rel="dns-prefetch" href="https://refit-storage-prod.s3.ap-northeast-2.amazonaws.com" />

효과

  • 실제 요청 흐름과 맞지 않는 힌트 제거

5) 적용 범위

적용

  • 새로 업로드되는 프로필 이미지
  • /me, /me/edit 프로필 이미지 렌더링

미적용

  • 기존 S3에 저장된 대용량 이미지
  • S3 캐시 정책 (인프라 영역)

중요 포인트

기존 이미지는 그대로 남아있기 때문에
Lighthouse에서 큰 이미지가 계속 보일 수 있음

6) 운영(S3)에서 필요한 설정

권장 캐시 정책

Cache-Control: public, max-age=31536000, immutable

운영 전략

  • 파일명 해시 기반 버저닝 유지
  • 캐시 무효화 대신 새 키 배포 전략

7) 트레이드오프

장점

  • 이미지 전송 용량 감소
  • LCP 안정성 개선
  • 업로드 자산 품질 표준화

고려사항

  • 클라이언트 전처리로 업로드 직전 CPU 사용 증가
  • 기존 이미지 백필 없으면 개선 효과가 점진적
  • /_next/image 최적화 경로 정상 동작 필요

8) 결론

이번 개선은 렌더링 시점 최적화와 자산 생성 시점 최적화를 동시에 적용한 구조 개선입니다.

핵심은 다음 한 문장으로 요약됩니다.

프로필 이미지를 업로드 시점에서 작게 만들고,
화면에서는 LCP 우선순위를 명확히 부여한다.

Clone this wiki locally