Skip to content

perf(web): 홈·전 [locale] 라우트가 완전 dynamic — 익명 방문도 매 요청 SSR + 백엔드 왕복 (엣지/ISR 캐시 0) #942

Description

@cocoyoon

증상 (프로덕션 실측, 2026-07-13)

https://decoded.style/en 반복 요청 — 매번:

  • cache-control: private, no-cache, no-store, max-age=0, must-revalidate
  • x-vercel-cache: MISS (5/5)
  • x-vercel-id: icn1::iad1::… (엣지 서울, 함수 버지니아)
  • HTML TTFB ~0.75–1.0s

next build: /[locale] 및 모든 /[locale]/*ƒ (Dynamic) server-rendered on demand.

원인 (분석)

app/[locale] 세그먼트가 next-intl(v4.13) 정적 렌더 조건 미충족:

  • [locale]/layout.tsxsetRequestLocale 호출하나 page.tsx·(shell)/layout.tsx미호출
  • generateStaticParams 부재 → 빌드타임 locale 미확정
  • NextIntlClientProvider 가 명시적 locale/messages 없이 컨텍스트(헤더) 의존 → dynamic 유발 후보

(로컬에서 generateStaticParams 추가·미사용 searchParams 제거만으로는 ƒ 유지 확인 → 위 3개를 함께 적용해야 함.)

임팩트

익명 방문자 전원이 매 요청 풀 SSR + 6개 백엔드 fetch(각 api.decoded.style, cf-cache-status: DYNAMIC origin hit)를 부담. 홈 개인화(인사말·For you·우측 레일)는 전부 클라이언트 사이드라 서버 HTML 은 익명 유저에게 동일 → ISR/엣지 캐시 대상인데 캐시 0.

제안

[locale] 정적/ISR 화:

  • 모든 layout + page 에 setRequestLocale(locale)
  • [locale]/layout.tsxgenerateStaticParams (routing.locales)
  • NextIntlClientProvider 에 명시적 locale+messages
  • 미사용 searchParams(page.tsx — await 만 하고 값 미사용) 제거
  • 필요 시 route-segment export const revalidate = 60

검증: next build 에서 /[locale] 가 ISR(/revalidate 표기)로 전환 + prod cache-control/x-vercel-cache: HIT + 로그인/로그아웃 홈 정상 동작.

관련

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions