DevLog

엔지니어링 블로그를 한 곳에서 탐색하고, 최근 발행 흐름을 빠르게 파악할 수 있는 서비스 입니다.

Quick Links

  • Latest Feed
  • Engineering Directory

Support

  • 소개
  • 개인정보처리방침

Contribute

  • 원하는 블로그 추가 (준비 중)
  • Feedback

© 2026 DevLog Inc. All rights reserved.

본 사이트는 공개 RSS 피드를 통해 콘텐츠를 수집하며, 모든 콘텐츠의 저작권은 원저작자에게 있습니다.

Back to Feed
Read Original

Contents

Continue Reading

  • More from 쏘카
  • Related reads#CloudFront
#DevOps

S3 + CloudFront 기반 SPA 배포에서 캐시와 fallback 전략 설계하기

S3 + CloudFront 기반 SPA 배포에서 캐시와 fallback 전략 설계하기
01

Summary

ChunkLoadError 정면 돌파! S3+CloudFront 환경에서 무결점 SPA 배포 설계하기

캐시 제어 분리와 정교한 라우트 fallback으로 배포 후 웹뷰 에러를 완벽하게 방어하는 시니어의 인프라 튜닝 가이드

이 아티클은 Vite 기반 React SPA를 S3와 CloudFront로 배포할 때 발생하는 청크 로드 에러의 원인을 파헤치고 이를 근본적으로 해결하는 과정을 담고 있습니다. CDN 캐시 정책 세분화, 좁은 범위의 라우트 rewrite, 그리고 프론트엔드 런타임 방어 전략을 연결하여 일관성 있는 배포 아키텍처를 제시합니다. 특정 프레임워크에 종속되지 않고 범용적으로 활용할 수 있는 SPA 배포 표준 계약 규격을 확인할 수 있습니다.

  • 01index.html(재검증)과 hashed assets(영구 캐시)의 캐시 수명 주기 명확한 이원화
  • 02CloudFront Function을 활용하여 확장자가 없는 순수 SPA 라우트 경로만 index.html로 정밀 rewrite 설정
  • 03CI/CD 파이프라인 개편을 통해 파일 성격별 S3 메타데이터 부여 및 불필요한 전체 무효화(/*) 방지
  • 04런타임 환경에서 청크 로딩 실패 감지 시 무한 루프를 막는 1회성 자동 페이지 복구(reload-once) 메커니즘 구축
  • 05동일한 배포 사상을 preview Nginx 환경에도 일관되게 정렬하는 확장 표준 정의

+RECOMMENDATION

S3와 CDN 조합으로 프론트엔드 정적 파일을 배포하고 있으나, 신규 배포 후 기존 사용자 세션에서 간헐적인 화면 멈춤이나 리소스 로드 에러를 겪고 있는 프론트엔드 엔지니어 및 인프라 담당자에게 적극 추천합니다.

The Problem

S3와 CloudFront를 사용하는 SPA 배포 환경에서 새 배포가 진행된 후, 사용자가 다른 경로로 이동할 때 구버전 런타임이 이미 삭제된 구버전 청크 파일을 요청하여 ChunkLoadError가 발생했습니다. 이 과정에서 CloudFront의 전역 Custom Error Response 설정이 누락된 JS 에셋 요청을 index.html 200 응답으로 잘못 반환하여 MIME 타입 불일치 에러를 유발했습니다.

The Solution

index.html(no-cache)과 해시된 에셋(immutable)의 캐시 메타데이터를 분리하여 S3에 업로드하고, 전역 Custom Error 설정을 제거하는 대신 CloudFront Function을 통해 확장자 없는 라우트만 index.html로 rewrite했습니다. 또한 CloudFront 무효화 범위를 엔트리 파일로 좁히고, 프론트엔드 단에서 청크 에러 발생 시 세션 저장소를 활용해 1회 새로고침하는 방어 로직을 적용했습니다.

The Result

정적 에셋 유실 시 HTML이 반환되는 MIME 타입 오류가 완전히 해결되어 실패 원인을 명확히 인지할 수 있게 되었으며, 이미 페이지를 열어두었던 사용자들도 오류 발생 시 자동으로 화면을 새로고침하여 최신 버전으로 정상 복구되는 경로가 마련되었습니다.

Trade-off

인프라 차원의 대응만으로는 구버전 세션의 에셋 요청 실패를 완벽히 막을 수 없기 때문에, 프론트엔드 애플리케이션의 에러 바운더리와 라우터 단에서 청크 에러 감지 및 재시도 로직을 수동으로 관리하고 구현해야 하는 관리 비용이 발생합니다.

03

Key Concepts

Concept · 01

SPA Fallback

클라이언트 사이드 라우팅을 수행하는 SPA에서 서버에 실제 물리 파일이 존재하지 않는 URL 경로로 직접 접속했을 때, 웹 서버나 CDN이 진입점인 index.html을 반환하여 브라우저에서 올바른 페이지를 렌더링하도록 돕는 라우팅 지원 기술입니다.

  • 기존의 무분별한 전역 403/404 Custom Error Response 방식을 제거했습니다.
  • CloudFront Function을 통해 확장자가 없는 순수 라우트 요청에 한해서만 index.html로 연결되도록 기능을 제한했습니다.
Concept · 02

Immutable Cache

빌드 결과물 내에 파일 내용에 기반한 고유 해시 값이 부여되는 정적 자원들에 대해, 브라우저가 매번 유효성 재검증을 하지 않고 무기한 캐시를 유지하도록 지시하는 최적화 캐싱 기법입니다.

  • Vite 번들링을 통해 생성된 hashed assets에 Cache-Control: public, max-age=31536000, immutable 메타데이터를 적용했습니다.
  • 전체 무효화(/*) 대신 엔트리 중심의 무효화를 적용해 에지에 올라간 해시 에셋들의 캐시 유지율을 보존했습니다.
Concept · 03

Reload-Once 방어 전략

이미 구버전 리소스를 올려 실행 중인 브라우저 메모리 상에서 배포로 인해 누락된 에셋을 요청할 때 에러가 발생하면, 이를 감지하고 세션 스토리지를 활용해 단 한 번만 강제로 화면을 새로고침하여 최신 자원을 다시 받도록 구현하는 복구 패턴입니다.

  • Vite의 전역 preload 에러 이벤트인 'vite:preloadError'를 감지하여 유실된 리소스 요청 실패 상황을 조기에 캐치했습니다.
  • 동일 시그니처에 대해 sessionStorage 기록을 확인해 중복 새로고침을 막음으로써 자동 루프 발생을 방어하고 최종 fallback 안내 UI를 제공했습니다.
Continue reading · same source

쏘카More from 쏘카

View all posts from 쏘카
  • 쏘카 디자인 시스템 2.0 개발기 2편: 기술로 굴리기(웹)

    Design SystemReactComponent Architecture
    6개월 전
  • 쏘카 디자인 시스템 2.0 개발기 1편: 시스템으로 굴리기(웹)

    Design SystemFigmaFigma Plugin
    6개월 전
  • Node.js 컨테이너, 왜 깔끔하게 안 죽을까? (feat. Graceful shutdown)

    Node.jsKubernetesDocker
    7개월 전
  • 쏘카프레임 - 블루투스 모듈

    BluetoothBLEMobile Architecture
    7개월 전
  • 쏘카프레임 - 앱 프레임워크와 개발자 경험

    Socar Frame개발자 경험Android
    7개월 전

Related reads#CloudFront

Explore #CloudFront
우아한형제들·Proxy

배포 없이 앱과 로컬 웹을 잇다

#CloudFront3주 전

Source

쏘카
쏘카
Engineering Blog

Published · June 23, 2026

Topics

CloudFrontS3SPACachingCI-CD