본문으로 건너뛰기

버그 제보

이상한 점을 알려 주시면 고칠게요. 지금 보고 있는 페이지와 브라우저 정보가 함께 담겨요.

페이지:

Frontend

PWA와 서비스 워커 캐시 전략

작성 2026. 10. 21.추가
목차13개 항목
출처와 참고

Aaron Gustafson의 「웹 프로젝트는 PWA이어야 한다」(웹액츄얼리 번역, 2017.09)와 「PWA 시대의 캐시 전략」(웹액츄얼리 번역, 2020.09)을 바탕으로, web.dev의 「Learn PWA」 강좌의 PWA 개요·시작하기 모듈과 WebKit 블로그로 지원 범위를 보강해 재구성한 노트다. 체크리스트 세부는 「What makes a good Progressive Web App?」로 보강했다.

PWA란

프로그레시브 웹 앱(Progressive Web App)은 운영 체제와 더 깊이 연결될 수 있는 웹사이트다. "앱"이라는 단어는 마케팅 용어일 뿐이다. 기술 요건은 세 가지가 전부다.

요건이유
HTTPSOS 권한에 가까운 API를 쓰므로 보안 연결이 전제다(HTTPS 전환)
웹 앱 매니페스트이름·아이콘·시작 URL을 담은 JSON. <link rel="manifest">로 연결한다
서비스 워커네트워크 요청을 가로채 캐시·오프라인·푸시를 처리하는 백그라운드 스크립트

흔한 오해와 달리 JS 프레임워크나 SPA가 필요하지 않고, 설치가 필수도 아니며, 모바일·Android 전용도 아니다. 서비스 워커와 매니페스트는 모든 주요 브라우저가 지원한다.

기능지원 범위 (2026년 기준)
서비스 워커·Cache API모든 주요 브라우저
설치Chromium 계열은 데스크톱·Android 모두. Safari는 iOS·iPadOS의 「홈 화면에 추가」(26부터 매니페스트 없이도 기본으로 웹 앱으로 열린다)와 macOS Sonoma 이상의 「Dock에 추가」. Firefox는 Android와 Windows(143부터 작업 표시줄 웹 앱)
웹 푸시주요 브라우저. iOS·iPadOS는 16.4부터 홈 화면에 추가한 웹 앱에서만
백그라운드 동기화Chromium 계열만. 다른 브라우저에서는 다음 방문 때 재시도하는 식으로 대체한다

플랫폼별 설치 방식과 설치 기준은 PWA 설치와 설치 유도에 정리했다.

설치된 PWA가 얻는 것

설치하면 PWA는 네이티브 앱처럼 동작한다. 홈 화면·런처·시작 메뉴 아이콘, OS 앱 검색 노출, 브라우저 UI 없는 자기 창, URL 처리·제목 표시줄 같은 OS 통합, 오프라인 동작이다. 웹의 장점(링크로 공유, 검색, 코드베이스 하나, 스토어 심사 없는 배포와 늘 최신 버전)은 그대로 남는다. 원하면 Google Play·Microsoft Store·App Store에도 올릴 수 있다.

과제도 있다. 브라우저마다 지원 기능이 다르고(특히 iOS·iPadOS의 Safari), 사용자는 사이트를 설치할 수 있다는 사실을 잘 모른다. 주요 브라우저·OS가 업데이트될 때마다 각 플랫폼에서 시험하고 대체 경로를 둔다.

시작하는 네 가지 방법

방법내용
설치 가능하게 만들기기본 매니페스트 + 오프라인 페이지 + 핵심 CSS·JS를 캐시하는 서비스 워커. 성능도 함께 좋아진다
기능 하나에 집중푸시 알림, 파일 처리처럼 사용자·사업에 효과가 큰 기능 하나부터
한 흐름만 완성영상 재생, 탑승권처럼 한 사용자 여정을 오프라인 우선으로 끝까지
처음부터리디자인이나 새 프로젝트일 때. 서비스 워커를 설계 초기부터 넣는다

체크리스트

핵심더 나은 PWA
빠르게 시작하고 빠르게 유지연결 없이 되는 기능은 오프라인으로
모든 브라우저에서 동작(같을 필요는 없다)완전한 접근성: 스크린 리더·키보드·포커스·대비
모든 화면 크기에 반응검색으로 찾을 수 있게(canonical URL, 색인 가능한 콘텐츠)
브라우저 기본 대신 자체 오프라인 페이지어떤 입력 방식이든, 화면 크기와 무관하게
설치 가능권한 요청 전에 맥락 설명, 쓸 수 있는 곳에서 강력한 기능 사용
건강한 코드: 알려진 취약점이 있는 라이브러리·폐기된 API·document.write()·passive가 아닌 스크롤 리스너를 쓰지 않고, 분석·서드파티 스크립트가 실패해도 앱이 깨지지 않게
  • 「모든 브라우저에서 동작」은 점진적 향상으로 만든다. 핵심 기능을 가장 단순한 기술(HTML 폼의 POST 제출)로 먼저 만들고, 기능 감지로 확인한 뒤 JS 검증·AJAX 제출을 덧입힌다.
  • 알림·위치·자격 증명 같은 권한 프롬프트는 페이지 로드 때 띄우지 않는다. 필요한 순간에 이유를 먼저 보여 준 뒤 요청해야 수락률과 신뢰가 지켜진다.
  • 과거에는 Lighthouse에 PWA 점수 영역이 있었지만 Lighthouse 12(2024)에서 빠졌다. 설치 가능 여부는 DevTools 애플리케이션 > 매니페스트 패널에서 확인한다.

자세한 주제는 각 노트에 있다.

주제노트
서비스 워커 등록·스코프·생명주기·업데이트·디버깅서비스 워커 등록·스코프·생명주기와 업데이트
Cache Storage, fetch 응답 전략, Workbox서비스 워커 캐싱과 응답 전략
IndexedDB, 할당량, 영속 저장, 백그라운드 동기화PWA 오프라인 데이터와 저장소 관리
매니페스트 필드, 아이콘, 표시 방식웹 앱 매니페스트
설치 기준, 플랫폼별 설치, 설치 프롬프트PWA 설치와 설치 유도
앱다운 CSS, 창 관리PWA 앱 경험 설계와 창 관리
푸시, 배지, 공유, 파일, 하드웨어 APIPWA 기능과 OS 통합

사이트 종류별로 얻는 것

모든 PWA가 공유하는 이점은 사실 웹 모범 사례다. 안전(HTTPS), 어떤 기기에서도 동작(반응형·점진적 향상), 찾기 쉬움(검색), 링크 가능(URL로 상태 복원), 네트워크 독립성(오프라인)이다. 그 위에 사이트 원형마다 쓸 기능이 다르다.

원형예쓸 만한 기능
정보 사이트회사·식당 소개오프라인·설치 효과는 작다. 위치·알림 정도
정기 간행 사이트블로그·뉴스·팟캐스트푸시 알림, 백그라운드 동기화로 아침 기사 미리 받기, "저장해 두고 읽기"
트랜잭션 사이트쇼핑·예약·뱅킹IndexedDB에 진행 중인 데이터 보관 후 재시도, 백그라운드 동기화, 완료 알림, 설치
소셜 서비스SNS재방문을 부르는 푸시, 빠른 첫 화면, 설치 후 연락처 등 시스템 API
소프트웨어메일·회계·편집기설치형 데스크톱 앱처럼 쓰기, 파일 시스템·오프라인 저장
기관 사이트대학·대기업서비스 워커와 매니페스트의 범위(scope)를 경로별로 나눠 여러 PWA로 쪼갠다

정기 간행 사이트에서 본 페이지를 전부 캐시하지 않는다. 다시 볼 일이 거의 없는 콘텐츠로 디스크를 채울 뿐이다. 공통 CSS·JS만 캐시하고, 사용자가 원하는 글만 저장하게 한다.

캐시의 두 층

flowchart TB
  req["요청"] -->|"1. 서비스 워커가 있으면"| sw["fetch 이벤트에서 Cache API로 직접 응답할 수 있다"]
  req -->|"2. HTTP 캐시"| http["Cache-Control로 유효 기간을 정하고, 만료되면 재검증<br/>(If-None-Match/If-Modified-Since → 304 Not Modified 또는 200)"]
층누가 정하나핵심
HTTP 캐시서버 응답 헤더max-age로 기간, no-store로 금지, immutable로 영구 보관. 바뀌는 파일은 URL을 바꾼다
서비스 워커 캐시사이트의 JS 코드무엇을 언제 넣고 뺄지 직접 결정한다. 출처(origin)마다 따로 격리된다

브라우저가 요청을 처리하는 전체 순서는 브라우저 렌더링 과정의 내비게이션 단계에 정리했다. Cache Storage API와 fetch 이벤트의 응답 전략(캐시 우선·네트워크 우선·stale-while-revalidate 등)은 서비스 워커 캐싱과 응답 전략에 있다. 이 노트의 아래 전략은 그 위에서 무엇을 얼마나 요청하고 캐시할지를 다룬다.

캐시 전략: 요청에 의도를 담는다

서비스 워커가 생겼다고 기본이 바뀌지 않는다. 필요한 것만, 가능한 한 작게 요청한다.

1. 필요한 것만 요청한다

미디어는 주목을 끄는 데 강하지만, 사용자가 기사를 읽기 시작하면 "있으면 좋은 것"으로 내려간다. 의미 없는 스톡 이미지를 넣고 싶은 충동부터 참는다.

2. 가장 작은 파일을 요청한다

  • <picture>의 <source type>으로 AVIF·WebP를 먼저, JPEG를 나중에 둔다. 브라우저는 지원하는 첫 소스를 고른다. 동영상도 <video> 안의 <source> 순서로 같은 원리를 쓴다.
  • srcset·sizes로 화면에 맞는 크기를 고르게 한다(반응형 이미지).
  • 서버가 Accept 헤더를 보고 형식을 바꿔 줄 수도 있다(이미지 CDN).

3. 가능한 한 늦게 요청한다

<img loading="lazy">는 뷰포트에 가까워질 때까지 이미지를 미룬다. 지원하지 않는 브라우저는 속성을 무시하므로 안전하다.

4. 상황과 중요도에 따라 응답한다

미디어를 세 등급으로 나누고, 네트워크 상태에 따라 다르게 다룬다.

미디어빠른 네트워크데이터 절약 모드느린 네트워크오프라인
필수 (차트·도표)받는다받는다받는다대체 이미지
있으면 좋음받는다대체 이미지대체 이미지대체 이미지
불필요뺀다뺀다뺀다뺀다
  • 서비스 워커 설치 단계에서 대체 이미지(fallback) 를 미리 캐시해 두고, 네트워크 요청이 실패하면 그것으로 응답한다.
  • 데이터 절약 설정을 켠 브라우저는 요청에 Save-Data: on 헤더를 붙인다. 서비스 워커에서 이 헤더를 보고 "있으면 좋음" 이미지를 대체 이미지로 바꾼다.
  • 필수 이미지와 나머지를 디렉터리나 도메인으로 나눠 두면 서비스 워커에서 정규식으로 구분하기 쉽다.

캐시를 깨끗하게 유지한다

디스크에 쓸 권한에는 아껴 쓸 책임이 따른다.

콘텐츠전략
분량이 정해진 것 (온라인 책)전부 캐시해 오프라인으로 읽게 해도 된다
끝없이 늘어나는 것 (뉴스)캐시 그룹마다 개수 상한을 둔다. 예: 페이지 5개, 이미지 75개
// 캐시 이름에 버전을 붙이고, 그룹마다 상한을 둔다
const caches_ = {
  static: { name: `${version}-static` },
  pages:  { name: `${version}-pages`, limit: 5 },
  images: { name: `${version}-images`, limit: 75 },
}
  • 버전을 바꾸면 이전 캐시를 한꺼번에 무효화할 수 있다.
  • 페이지가 로드될 때 postMessage로 서비스 워커에 정리 요청을 보내면, 별도 스레드에서 상한을 넘는 오래된 항목을 지운다.
  • Cache API는 항목의 사용 빈도나 크기를 알려 주지 않아 "넣은 순서"로만 지우게 된다는 한계가 있다.

정리

  • PWA는 HTTPS·매니페스트·서비스 워커를 갖춘 더 나은 웹사이트다. 설치와 오프라인은 선택이다.
  • 사이트 원형마다 쓸 기능이 다르다. 푸시·백그라운드 동기화는 재방문이 잦은 사이트에서 효과가 크다.
  • 캐시 전략의 출발점은 여전히 필요한 것만, 작게, 늦게 요청하는 것이다.
  • 미디어를 필수·있으면 좋음·불필요로 나누고 Save-Data와 네트워크 상태에 맞춰 대체 이미지를 쓴다.
  • 캐시에 상한과 버전을 두어 사용자의 디스크를 존중한다.

관련 노트: 서비스 워커 등록·스코프·생명주기와 업데이트, 서비스 워커 캐싱과 응답 전략, PWA 설치와 설치 유도, 브라우저 렌더링 과정, 반응형 이미지, 책임감 있는 자바스크립트, CDN, HTTP 프로토콜, DevTools Application 패널: 저장소·서비스 워커, 리소스 힌트와 미리 불러오기

원본 기록8

댓글

GitHub 계정으로 댓글을 남길 수 있어요.