리소스 캐싱/프리캐시/SW — 코드레벨 동작 흐름 P2코드레벨

마지막 업데이트 2026-07-22

작성일: 2026-06-14 대상: 개발자 — 활동 리소스 캐싱/입장 게이트 파악 핵심 파일: hooks/use-resource-cache.ts

개요 · 범위

수업 활동의 리소스(이미지·영상·오디오)를 입장 전 미리 받아 Cache Storage에 저장(프리캐시)하고, 재생 시 캐시에서 꺼내 쓰는 시스템. 다운로드 실패 시 입장을 차단(#15)해 수업 중 끊김을 방지한다.

저수준 다운로드(Range 이어받기·재시도)는 별도 문서: 리소스 다운로드 HTTP Range 이어받기·재시도/실패 처리. 본 문서는 캐시 계층(버전 키·프리캐시·lazy·입장 게이트).

버전 캐시 키 getCacheKey L83

`https://dubu-cache/${fileName}?v=${updatedAt}`
  • 가상 도메인 + updatedAt(버전) 쿼리로 키 생성. 리소스가 갱신되면 updatedAt이 바뀌어 자동 캐시 무효화(이전 버전 키는 더 이상 매칭 안 됨).
  • 가상 절대 URL이라 페이지가 달라도 같은 키로 일관 조회(Cache Storage는 URL 키 기반).

프리캐시 cacheResources L88

  1. 1Cache 열기: caches.open(CACHE_NAME). 실패(시크릿 모드/스토리지 비활성)면 이벤트 추적 후 throw → 입장 차단.
  2. 2메타데이터: POST /api/resources/urls {fileNames, isLowPerformanceDevice} → 파일별 {url(presigned), updatedAt}. (저사양이면 저화질 URL) 이 단계 실패는 서버 presigned 발급 문제로 S3 다운로드 실패와 별도 추적.
  3. 3캐시 점검: 각 파일의 버전 키로 cache.match → 있으면 완료 처리, 없으면 다운로드 목록에 추가. 메타데이터 없는 파일은 failed에 넣고 fail-fast(받아도 입장 차단되므로 다운로드 생략).
  4. 4순차 다운로드: 네트워크 혼잡 방지 위해 한 개씩 fetchResumable(Range 이어받기+3회 재시도) → blob → new Response(blob)cache.put(성공 후에만).
  5. 5반환 { failed }: 3회 재시도 후에도 못 받은 목록. 호출부(#15)가 비어있지 않으면 입장 차단.

onProgress(current, total)로 진척 통지(호스트 입장 승인 UI의 캐싱 진행률).

지연 로드(lazy) getResource ~L262

프리캐시되지 않은 리소스를 재생 시점에 on-demand로: presigned URL 발급 → 버전 키 cache.match → 없으면 fetchResumablecache.put. 인메모리 responseCacheMap/blobUrlsMap으로 같은 세션 내 재요청 가속.

Service Worker · 정리

  • PWA/SW: service worker 등록·정리는 components/ui/service-worker-clean-up.tsx, next.config.mjs(PWA 설정). 오프라인/캐싱 전략 지원.
  • 캐시 전체 삭제: caches.delete(CACHE_NAME)(clearCache).
  • 리소스 처리 폴링: use-resource-processing — 업로드 후 비동기 트랜스코딩 상태 폴링(완료돼야 프리캐시 가능).
  • 리소스 수집: lib/resource-collector.ts — 활동에서 필요한 파일명 목록 추출(cacheResources 입력).

함정 · 주의

  • 버전 키 의존: updatedAt이 안 바뀌면 갱신된 리소스가 옛 캐시로 재생됨. 리소스 변경 시 updatedAt 갱신 필수.
  • cache.put은 성공 후에만: 부분 다운로드를 캐시하면 깨진 리소스가 영구 잔존. blob 완성 후에만 put.
  • 입장 게이트: failed가 비어있지 않으면 #15가 입장 차단. fail-fast(메타 누락)는 다운로드를 건너뛰고 즉시 차단.
  • Cache API 미지원 환경: 시크릿 모드/스토리지 비활성 시 caches.open 실패 → 입장 불가. 인앱 브라우저 주의.
  • 순차 다운로드: 병렬이 빠르지만 약한 기기/망에서 혼잡 → 순차 선택. 대량 리소스 시 입장 지연 가능(progress로 표시).

파일 · 라인 레퍼런스

파일/심볼역할
use-resource-cache.ts (cacheResources L88, getCacheKey L83)프리캐시·lazy·버전 키
lib/fetch-resumable.tsRange 이어받기·재시도 다운로드
hooks/use-resource-processing.ts비동기 처리 상태 폴링
lib/resource-collector.ts활동 리소스 파일명 수집
api/resources/urls/route.tspresigned URL + updatedAt 발급
components/ui/service-worker-clean-up.tsx, next.config.mjsSW/PWA