Skip to content
Back to Blog
#pwa #web #javascript #serviceworker

PWA 완벽 가이드: 개발부터 운영까지

5 min read

Progressive Web App의 핵심 개념부터 실전 구현, 배포, 운영까지 상세하게 다루는 완벽 가이드. Service Worker, 캐싱 전략, 오프라인 지원, 성능 최적화까지 실무에 필요한 모든 것을 알아봅니다.

Progressive Web App(PWA)는 웹과 네이티브 앱의 장점을 결합한 차세대 웹 애플리케이션 기술입니다. 이 가이드에서는 PWA의 핵심 개념부터 실전 구현, 배포, 그리고 운영까지 실무에 필요한 모든 내용을 상세하게 다룹니다.

샘플 프로젝트: 이 가이드의 전체 코드는 GitHub 샘플 프로젝트에서 확인할 수 있습니다.

PWA란 무엇인가?

PWA는 웹 기술로 만들어진 애플리케이션이지만, 네이티브 앱처럼 동작하는 웹 애플리케이션입니다.

주요 특징

  • 설치 가능: 홈 화면에 추가하여 앱처럼 실행 가능
  • 오프라인 동작: 네트워크가 없어도 기본 기능 제공
  • 푸시 알림: 사용자 재참여를 위한 알림 기능
  • 빠른 로딩: 캐싱을 통한 즉각적인 로딩
  • 반응형: 모든 디바이스에서 완벽한 동작
  • 안전: HTTPS를 통한 보안 연결 필수

PWA vs 네이티브 앱

특징 PWA 네이티브 앱
설치 브라우저에서 직접 설치 앱 스토어 필요
업데이트 자동 업데이트 수동 업데이트
개발 비용 낮음 (웹 기술) 높음 (플랫폼별 개발)
배포 즉시 배포 앱 스토어 승인 필요
크기 작음 상대적으로 큼
오프라인 제한적 지원 완전 지원
성능 우수 최고

PWA의 핵심 구성 요소

PWA는 세 가지 핵심 기술로 구성됩니다:

1. Web App Manifest

Manifest 파일은 PWA의 메타데이터를 정의하는 JSON 파일입니다. 앱 이름, 아이콘, 표시 방식 등을 설정합니다.

주요 속성:

  • name: 앱의 전체 이름 (설치 프롬프트에 표시)
  • short_name: 홈 화면에 표시될 짧은 이름 (12자 이내 권장)
  • display: 앱 표시 모드
    • standalone: 네이티브 앱처럼 독립 실행 (권장)
    • fullscreen: 전체 화면
    • minimal-ui: 최소한의 UI 표시
    • browser: 일반 브라우저 모드
  • icons: 다양한 크기의 아이콘 (최소 192x192, 512x512 필수)
  • start_url: 앱 시작 시 로드될 URL
  • theme_color: 브라우저 UI 색상
  • background_color: 스플래시 화면 배경색

구현 팁:

  • 아이콘은 반드시 192x192와 512x512 크기를 포함해야 합니다
  • purpose: "maskable"을 설정하여 Android 적응형 아이콘 지원
  • screenshots 속성으로 앱 스토어 스타일의 스크린샷 추가 가능

2. Service Worker

Service Worker는 PWA의 심장부입니다. 브라우저와 네트워크 사이에서 프록시 역할을 하며, 오프라인 지원과 성능 최적화의 핵심입니다.

Service Worker 생명주기

  1. 설치 (Install)

    • Service Worker가 처음 등록될 때 실행
    • 정적 리소스를 캐시에 저장
    • skipWaiting()으로 즉시 활성화 가능
  2. 활성화 (Activate)

    • 이전 버전의 Service Worker를 대체
    • 오래된 캐시를 삭제하는 시점
    • clients.claim()으로 즉시 제어권 획득
  3. 패치 (Fetch)

    • 모든 네트워크 요청을 가로챔
    • 캐싱 전략을 적용하는 시점

주의사항

  • Service Worker는 HTTPS에서만 동작 (localhost 예외)
  • 파일 경로는 절대 경로 사용 권장
  • 캐시 버전 관리를 통한 업데이트 전략 필수
  • 에러 처리를 반드시 구현해야 함

3. HTTPS

PWA는 보안을 위해 HTTPS를 필수로 요구합니다.

HTTPS가 필요한 이유:

  • Service Worker는 강력한 기능이므로 보안 연결 필요
  • 푸시 알림, 지오로케이션 등 민감한 API 접근
  • 중간자 공격(Man-in-the-middle) 방지

캐싱 전략

효과적인 PWA를 위해서는 적절한 캐싱 전략이 핵심입니다.

1. Cache First (캐시 우선)

동작 방식: 캐시에서 먼저 찾고, 없으면 네트워크 요청

적합한 경우:

  • 정적 리소스 (JS, CSS, 이미지, 폰트)
  • 자주 변경되지 않는 콘텐츠
  • 빠른 응답이 중요한 경우

장점: 매우 빠른 로딩 속도
단점: 오래된 콘텐츠를 보여줄 수 있음

2. Network First (네트워크 우선)

동작 방식: 네트워크를 먼저 시도하고, 실패하면 캐시 사용

적합한 경우:

  • API 응답 데이터
  • 자주 변경되는 동적 콘텐츠
  • 최신 데이터가 중요한 경우

장점: 항상 최신 데이터 제공
단점: 네트워크가 느리면 전체적으로 느림

3. Stale While Revalidate (재검증하며 기존 데이터 사용)

동작 방식: 캐시된 데이터를 즉시 반환하면서 백그라운드에서 업데이트

적합한 경우:

  • 빈번히 변경되지만 즉시 반영이 필수는 아닌 콘텐츠
  • 사용자 경험이 중요한 콘텐츠
  • 뉴스 피드, 소셜 미디어 타임라인

장점: 빠른 로딩 + 최신 데이터 유지
단점: 구현이 복잡하고 데이터 일관성 관리 필요

4. Network Only (네트워크만 사용)

적합한 경우:

  • 절대 캐시하면 안 되는 데이터 (결제, 개인정보)
  • 실시간성이 중요한 데이터

5. Cache Only (캐시만 사용)

적합한 경우:

  • 오프라인 전용 콘텐츠
  • 사전에 다운로드한 콘텐츠

전략 선택 가이드

정적 리소스 (JS, CSS, 이미지, 폰트)
→ Cache First

API 데이터 (사용자 정보, 주문 내역)
→ Network First

콘텐츠 피드 (뉴스, 게시글)
→ Stale While Revalidate

실시간 데이터 (주식, 채팅)
→ Network Only

오프라인 페이지
→ Cache Only

오프라인 지원 구현

오프라인 페이지

모든 PWA는 최소한 오프라인 페이지를 제공해야 합니다. 사용자가 네트워크 없이 앱을 실행했을 때 빈 화면 대신 의미 있는 메시지를 보여줍니다.

오프라인 페이지 구현 요소:

  • 명확한 상태 표시 (“오프라인 상태입니다”)
  • 재시도 버튼
  • 앱의 브랜드 일관성 유지
  • 온라인 복구 시 자동 새로고침

네트워크 상태 감지

onlineoffline 이벤트를 사용하여 네트워크 상태를 실시간으로 감지할 수 있습니다.

구현 패턴:

  1. 네트워크 상태 UI 표시
  2. 오프라인 시 사용자에게 알림
  3. 온라인 복구 시 대기 중인 작업 실행
  4. 백그라운드에서 자동 동기화

Background Sync (백그라운드 동기화)

Background Sync는 오프라인 상태에서 발생한 작업을 온라인 복구 시 자동으로 처리하는 기능입니다.

사용 사례

  • 양식 제출
  • 댓글 작성
  • 좋아요, 북마크
  • 파일 업로드
  • 데이터 동기화

구현 고려사항

  • IndexedDB를 사용한 로컬 데이터 저장
  • 동기화 실패 시 재시도 로직
  • 사용자에게 동기화 상태 피드백
  • 중복 요청 방지

Push Notifications (푸시 알림)

푸시 알림은 사용자 재참여(Re-engagement)의 핵심 기능입니다.

알림 권한 요청

Best Practices:

  • 적절한 시점에 요청 (앱 첫 실행 시 즉시 요청 X)
  • 알림의 가치를 먼저 설명
  • 거부 시 재요청 전략 수립
  • 알림 설정 페이지 제공

푸시 알림 구현 단계

  1. VAPID 키 생성

    • 서버에서 공개/비공개 키 쌍 생성
    • 푸시 서비스 인증에 사용
  2. 구독 정보 저장

    • 사용자의 푸시 구독 정보를 서버에 저장
    • 구독 ID를 사용자와 연결
  3. 알림 전송

    • 서버에서 푸시 서비스로 알림 전송
    • Web Push Protocol 사용
  4. 알림 처리

    • Service Worker에서 push 이벤트 처리
    • notificationclick 이벤트로 사용자 액션 처리

알림 Best Practices

  • 제목과 본문을 명확하게
  • 아이콘과 배지로 시각적 차별화
  • 액션 버튼으로 직접 상호작용 제공
  • 진동 패턴으로 촉각 피드백
  • 알림 빈도 조절 (스팸 방지)

성능 최적화

리소스 우선순위

preload:

  • 현재 페이지에서 즉시 필요한 리소스
  • 중요한 CSS, JS, 폰트

prefetch:

  • 다음 탐색에서 필요할 수 있는 리소스
  • 낮은 우선순위로 로드

preconnect:

  • 외부 도메인에 미리 연결
  • DNS 조회, TLS 협상 시간 절약

코드 스플리팅

  • 초기 로딩 시간 단축
  • 필요한 코드만 로드
  • 동적 import 활용

이미지 최적화

  • 지연 로딩 (Lazy Loading)
  • WebP 형식 사용
  • 반응형 이미지 (srcset, picture)
  • Intersection Observer API 활용

캐시 크기 관리

캐시 정리 전략:

  • 최대 캐시 항목 수 제한 (예: 50개)
  • 오래된 캐시 자동 삭제 (예: 7일)
  • 정기적인 캐시 정리

앱 설치 프롬프트

설치 기준

브라우저는 다음 조건을 만족하면 자동으로 설치 프롬프트를 표시합니다:

  • ✅ manifest.json 파일이 유효함
  • ✅ Service Worker가 등록되어 있음
  • ✅ HTTPS로 제공됨
  • ✅ 사용자가 사이트와 일정 시간 상호작용함

커스텀 설치 프롬프트

beforeinstallprompt 이벤트를 사용하여 설치 프롬프트를 커스터마이징할 수 있습니다.

커스터마이징 이유:

  • 브랜드에 맞는 디자인
  • 적절한 타이밍 선택
  • 설치 가치 전달
  • 더 나은 전환율

iOS Safari 설치 안내

iOS Safari는 자동 설치 프롬프트를 지원하지 않습니다. 사용자에게 수동 설치 방법을 안내해야 합니다.

안내 단계:

  1. 하단의 공유 버튼 탭
  2. “홈 화면에 추가” 선택
  3. “추가” 확인

배포 및 HTTPS 설정

Let’s Encrypt를 사용한 무료 SSL

Let’s Encrypt는 무료로 SSL 인증서를 발급해주는 서비스입니다.

장점:

  • 완전 무료
  • 자동 갱신
  • 대부분의 웹 서버 지원

Certbot 도구 사용:

  • 인증서 자동 발급
  • 웹 서버 자동 설정
  • Cron으로 자동 갱신 설정

Nginx 설정 포인트

PWA를 위한 필수 설정:

  1. HTTPS 리다이렉트: 모든 HTTP 요청을 HTTPS로 리다이렉트

  2. HSTS 헤더: 브라우저가 항상 HTTPS로 접속하도록 강제

  3. Service Worker 헤더: Service Worker가 모든 경로를 제어할 수 있도록 허용

  4. 캐시 컨트롤:

    • HTML: 캐싱 안 함
    • JS/CSS: 장기 캐싱 (1년)
    • Service Worker: 캐싱 안 함
  5. Gzip 압축: 텍스트 리소스 압축으로 전송 크기 감소

테스팅 및 디버깅

Chrome DevTools

Application 탭:

  • Manifest 정보 확인
  • Service Worker 상태 및 로그
  • 캐시 스토리지 내용
  • IndexedDB 데이터

Network 탭:

  • Service Worker 필터링
  • 오프라인 모드 시뮬레이션
  • 캐시 히트/미스 확인

Lighthouse 감사

Lighthouse는 PWA 품질을 자동으로 평가하는 도구입니다.

평가 항목:

  • PWA 체크리스트 준수 여부
  • 성능 지표 (FCP, LCP, TTI 등)
  • 접근성
  • SEO
  • Best Practices

목표 점수: 90점 이상

PWA 필수 체크리스트

필수 요구사항

  • ✅ HTTPS로 서비스됨
  • ✅ 유효한 Web App Manifest
  • ✅ Service Worker 등록됨
  • ✅ 오프라인에서 200 응답
  • ✅ 모바일에서 빠른 로딩 (3G에서 3초 이내)
  • ✅ 크로스 브라우저 호환성
  • ✅ 페이지 전환이 즉각적
  • ✅ 각 페이지에 고유 URL

권장 사항

  • 🔄 오프라인 페이지 제공
  • 🔄 설치 프롬프트 커스터마이징
  • 🔄 푸시 알림 구현
  • 🔄 Background Sync 구현
  • 🔄 성능 최적화 (Lighthouse 90+)

운영 모니터링

분석 추적

PWA 특화 이벤트:

  • Service Worker 등록 성공/실패
  • 앱 설치/제거
  • 오프라인/온라인 전환
  • 푸시 알림 클릭
  • Background Sync 실행

주요 지표:

  • 설치율 (Install Rate)
  • 유지율 (Retention Rate)
  • 재참여율 (Re-engagement Rate)
  • 오프라인 사용 빈도
  • 평균 세션 시간

에러 추적

Service Worker 에러:

  • 등록 실패
  • 캐시 저장 실패
  • Fetch 에러

앱 에러:

  • JavaScript 런타임 에러
  • Promise rejection
  • 네트워크 요청 실패

성능 모니터링

Core Web Vitals:

  • LCP (Largest Contentful Paint): 2.5초 이하
  • FID (First Input Delay): 100ms 이하
  • CLS (Cumulative Layout Shift): 0.1 이하

보안 고려사항

Content Security Policy (CSP)

CSP는 XSS 공격을 방지하는 보안 헤더입니다.

PWA를 위한 CSP 설정:

  • worker-src 'self': Service Worker를 같은 출처에서만 로드
  • script-src: 스크립트 출처 제한
  • connect-src: API 엔드포인트 제한

민감한 데이터 처리

절대 캐시하지 말아야 할 데이터:

  • 개인 식별 정보 (PII)
  • 인증 토큰
  • 결제 정보
  • 의료 기록
  • 금융 데이터

접근성 (Accessibility)

PWA는 모든 사용자가 접근할 수 있어야 합니다.

키보드 네비게이션

  • 모든 기능을 키보드로 조작 가능해야 함
  • Tab 순서가 논리적이어야 함
  • 포커스 표시가 명확해야 함

스크린 리더 지원

  • role, aria-label, aria-live 속성 활용
  • 상태 변경 시 스크린 리더에 알림
  • 의미 있는 HTML 시맨틱 태그 사용

실전 구현 체크리스트

개발 단계

  • Manifest 파일 작성
  • Service Worker 구현
  • 캐싱 전략 선택
  • 오프라인 페이지 제작
  • 설치 프롬프트 구현
  • 푸시 알림 (선택사항)

테스트 단계

  • Lighthouse 감사 (90점 이상)
  • 다양한 브라우저 테스트
  • 오프라인 시나리오 테스트
  • 모바일 기기 실제 테스트
  • 네트워크 속도별 테스트 (3G, 4G, WiFi)

배포 단계

  • HTTPS 설정
  • 서버 캐시 헤더 설정
  • CDN 설정 (선택사항)
  • 모니터링 도구 설정
  • 에러 추적 설정

운영 단계

  • 성능 모니터링
  • 에러 로그 검토
  • 사용자 피드백 수집
  • 정기적인 업데이트
  • 보안 패치 적용

마치며

PWA는 단순히 기술적인 구현을 넘어 사용자 경험을 혁신하는 강력한 도구입니다.

시작하기

  1. 작게 시작: 먼저 Service Worker와 manifest.json만 추가
  2. 점진적 개선: 캐싱, 오프라인 지원을 단계적으로 추가
  3. 측정과 개선: Lighthouse로 측정하고 점수 향상
  4. 사용자 피드백: 실제 사용자의 의견을 반영

다음 학습 리소스

PWA는 지속적으로 발전하는 기술입니다. 새로운 API와 기능들이 계속 추가되고 있으니, 최신 트렌드를 주시하면서 사용자에게 최고의 경험을 제공하세요!

이 글 공유하기

💡 LifeTech Hub

삶을 업그레이드하는 기술과 지혜 - 재테크, 개발, AI, IT, 일상생활

Quick Links

Connect

© 2025 LifeTech Hub. Built with 💜 using SvelteKit

Privacy Terms RSS