목차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)은 운영 체제와 더 깊이 연결될 수 있는 웹사이트다. "앱"이라는 단어는 마케팅 용어일 뿐이다. 기술 요건은 세 가지가 전부다.
| 요건 | 이유 |
|---|---|
| HTTPS | OS 권한에 가까운 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 앱 경험 설계와 창 관리 |
| 푸시, 배지, 공유, 파일, 하드웨어 API | PWA 기능과 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
- 원문 (새 창) developers.google.com/web/progressive-web-apps/checklist
- 원문 (새 창) web.dev/learn/pwa
- 원문 (새 창) web.dev/learn/pwa/progressive-web-apps
- 원문 (새 창) web.dev/learn/pwa/getting-started
- 원문 (새 창) webkit.org/blog/13878/web-push-for-web-apps-on-ios-and-ipados/
- 원문 (새 창) webkit.org/blog/17333/webkit-features-in-safari-26-0/
- 원문 (새 창) webactually.com/2017/09/28/웹-프로젝트는-pwa이어야-한다1/
- 원문 (새 창) webactually.com/2020/09/23/PWA-시대의-캐시-전략/