Skip to content

fix: next/image sizes 누락·불일치로 인한 과대 이미지 요청 수정 #528

Description

@kanghaeun

버그 내용

next/imagesizes와 기기 DPR로 srcset 후보 중 하나를 골라 /_next/image?url=...&w=<폭>&q=75 를 요청하는데, sizes 를 안 주면 100vw 로 간주해 화면 전체 폭짜리 이미지를 받습니다.

fill 을 쓰면서 sizes 를 빠뜨렸거나, sizes 값이 실제 렌더 폭과 어긋난 곳이 4군데 있습니다.

기준: iPhone 14 (뷰포트 390px, DPR 3). 매치 화면의 w=640 은 e2e 실측값이고, 나머지는 같은 방식으로 계산한 값

1. sizes 누락 — fill 인데 값이 없음

product-image/index.tsx (담기 화면 장바구니 썸네일)

BaseImagesizes 를 전달하지 않습니다. 컴포넌트가 자기 크기를 이미 알고 있는데도 (SIZE_STYLE.sm.dimension = 68, lg = 200) 그 값이 sizes 로 이어지지 않습니다.

실제 렌더 폭 약 75px (장바구니 그리드 w-[45%] 2열)
필요한 요청 폭 256
실제 요청 폭 1200

TournamentBasketItem.tsx:53 (친구 프로필 뱃지)

<Image src={friendImageUrl} fill className="object-cover" />sizes 없음.
컨테이너가 부모의 35%라 가장 작은 이미지인데 가장 큰 걸 받습니다.

실제 렌더 폭 약 26px
필요한 요청 폭 96
실제 요청 폭 1200

2. sizes 값이 실제 렌더 폭과 어긋남

components/common/wish-card/index.tsx (위시 카드)

sizes="(max-width: 480px) calc(100vw - 40px - 8px), 216px" 인데,
wish-grid/index.tsx:31grid grid-cols-2 입니다. 즉 calc(...)한 줄 전체 폭이고
카드 하나는 그 절반입니다.

실제 렌더 폭 약 171px
필요한 요청 폭 640
실제 요청 폭 1080

item-info-screen/ItemDetailView.tsx, ItemImagePicker.tsx

둘 다 sizes="440px" 인데 컨테이너가 w-full 이고 부모(item-info-screen/index.tsx:60)에
px-5 가 걸려 있어 실제로는 약 350px 입니다.

실제 렌더 폭 약 350px
필요한 요청 폭 1080
실제 요청 폭 1920

왜 고쳐야 하나

  • 모바일 데이터: 20~30대 모바일 쇼핑 사용자가 타겟인데, 68px 자리에 1200px 이미지를 받으면 픽셀 면적 기준 20배 이상을 낭비합니다
  • LCP: 담기 화면과 위시 목록은 이미지가 곧 첫 화면입니다
  • /_next/image 최적화 비용: 큰 폭일수록 서버 리사이즈가 오래 걸리고 캐시도 더 씁니다
  • 캐시 키 분산: 같은 상품 이미지를 화면마다 다른 w 로 받으면 서로 캐시를 재사용하지 못합니다. 실제로 담기 화면(w=1200)과 매치 화면(w=640)이 그렇습니다

버그 수정

  • ProductImagesize variant(sm: 68, lg: 200)에서 sizes 를 유도해 BaseImage
    넘기고, fill 일 때는 호출부가 sizes 를 넘기도록 prop 을 열어둡니다
  • 친구 프로필 뱃지 — sizes 추가
  • 위시 카드 — 2열 그리드 기준으로 calc((100vw - 40px - 8px) / 2) 로 정정
  • item-info-screen — 440pxcalc(100vw - 40px) 계열로 정정
  • 재발 방지로 fill 사용 시 sizes 를 강제하는 린트 규칙 검토 (@next/next 룰셋 확인 필요)

Metadata

Metadata

Assignees

Labels

fixSomething isn't working

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions