레이블이 PWA인 게시물을 표시합니다. 모든 게시물 표시
레이블이 PWA인 게시물을 표시합니다. 모든 게시물 표시

20250116

PWA Manifest 작성 예제 (HTML 포함)

프로그레시브 웹 앱(PWA)은 웹과 네이티브 앱의 기능적 장점을 결합한 웹 애플리케이션입니다. PWA는 특정 기술과 표준 패턴을 사용하여 개발되며, 사용자에게 네이티브 앱과 유사한 경험을 제공합니다. 예를 들어, PWA는 네이티브 앱처럼 설치할 수 있고 오프라인에서도 작동하며, 푸시 알림과 같은 기능을 지원합니다.

웹 앱은 링크를 통해 쉽게 공유할 수 있고 접근성이 뛰어난 반면, 네이티브 앱은 운영체제와 더 잘 통합되어 부드러운 사용자 경험을 제공합니다. PWA는 이 두 가지 장점을 모두 활용하여 더 나은 사용자 경험을 제공합니다.

PWA의 주요 특징

PWA는 다음과 같은 특징을 가지고 있습니다:

  • 발견 가능: 검색 엔진을 통해 쉽게 찾을 수 있습니다.
  • 설치 가능: 네이티브 앱처럼 홈 화면에 추가할 수 있습니다.
  • 오프라인 지원: 네트워크 연결이 없어도 작동합니다(Service Worker 기술 활용).
  • 반응형 디자인: 모든 기기와 화면 크기에 최적화됩니다.
  • 푸시 알림: 사용자 재참여를 유도할 수 있습니다.
  • 보안성: HTTPS를 통해 안전하게 제공됩니다.

PWA 구현 방법

PWA를 구현하려면 다음 세 가지 핵심 요소가 필요합니다:

1. 웹 앱 매니페스트 파일(manifest.json)

매니페스트 파일은 PWA의 메타정보를 담고 있으며, 앱 이름, 아이콘, 시작 URL 등을 정의합니다.

{
  "name": "My PWA",
  "short_name": "PWA",
  "start_url": "/index.html",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#317EFB",
  "icons": [
    {
      "src": "icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

2. 서비스 워커(Service Worker)

서비스 워커는 백그라운드에서 실행되며, 캐싱, 오프라인 지원, 푸시 알림 등을 처리합니다.

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('pwa-cache').then(cache => {
      return cache.addAll(['/index.html', '/style.css', '/app.js']);
    })
  );
});

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(response => response || fetch(event.request))
  );
});

3. HTTPS

PWA는 보안을 위해 HTTPS 프로토콜에서만 동작합니다.

PWA의 성공 사례

PWA 도입 후 성공적인 결과를 얻은 사례가 많습니다:

  • Flipkart Lite: 인도의 전자상거래 플랫폼으로 PWA 도입 후 전환율이 70% 증가했습니다.
  • Twitter Lite: 데이터 사용량을 줄이고 로딩 속도를 개선하여 사용자 참여율이 크게 증가했습니다(세션당 페이지 수 +65%).
  • Pinterest: 로딩 속도를 단축하고 모바일 사용자 수를 두 배로 늘렸습니다.
  • Starbucks: 오프라인에서도 메뉴 탐색 및 주문이 가능하며, 모바일 주문 비율이 증가했습니다.

PWA 도입의 장점

PWA는 비교적 적은 노력으로도 큰 이점을 제공합니다:

  • 서비스 워커 캐싱: 빠른 로딩 시간과 데이터 절약.
  • 자동 업데이트: 변경된 콘텐츠만 업데이트 가능.
  • 네이티브 앱과 유사한 경험 제공: 홈 화면 아이콘 추가 및 전체 화면 실행.
  • 푸시 알림을 통한 재참여 유도: 전환율과 사용자 참여율 향상.

PWA 구현 예제

아래는 간단한 PWA 구현 예제입니다:

HTML 파일 (index.html)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My First PWA</title>
  <link rel="manifest" href="/manifest.json">
</head>
<body>
  <h1>Welcome to My PWA</h1>
  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/service-worker.js')
        .then(() => console.log('Service Worker registered'))
        .catch(err => console.error('Service Worker registration failed', err));
    }
  </script>
</body>
</html>

Service Worker를 사용해 PWA를 오프라인에서 동작하게 만들기

Service Worker란?

Service Worker는 브라우저와 네트워크 사이에서 동작하는 가상 프록시로, 웹 애플리케이션의 자원을 캐싱하고 네트워크 상태에 따라 적절한 응답을 제공합니다. 이를 통해 사용자는 오프라인 상태에서도 애플리케이션을 사용할 수 있습니다.

Service Worker는 독립된 스레드에서 실행되며, DOM에 직접 접근하지 않습니다. 비차단형 API를 사용하며, Promise 기반으로 설계되어 효율적인 작업 처리가 가능합니다.

Service Worker 등록하기

Service Worker를 사용하려면 먼저 브라우저에 등록해야 합니다. 아래는 간단한 등록 코드입니다:


if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then(registration => console.log('Service Worker 등록 성공:', registration))
    .catch(error => console.log('Service Worker 등록 실패:', error));
}
                

위 코드는 브라우저가 Service Worker API를 지원하는지 확인한 후, Service Worker 파일(sw.js)을 등록합니다.

Service Worker의 수명 주기

Service Worker는 설치(install), 활성화(activate), 그리고 fetch 이벤트를 포함한 여러 단계로 구성된 수명 주기를 가집니다.

1. 설치 (Install)

설치 단계에서는 캐시를 초기화하고 필요한 자원을 캐싱합니다:


self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('app-cache-v1').then(cache => {
      return cache.addAll([
        '/',
        '/index.html',
        '/style.css',
        '/app.js',
        '/images/logo.png'
      ]);
    })
  );
});
                

2. 활성화 (Activate)

활성화 단계에서는 오래된 캐시를 정리할 수 있습니다:


self.addEventListener('activate', event => {
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheName !== 'app-cache-v1') {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});
                

3. 요청 가로채기 (Fetch)

fetch 이벤트를 통해 네트워크 요청을 가로채고 캐시된 자원을 반환하거나 네트워크에서 데이터를 가져옵니다:


self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(response => {
      return response || fetch(event.request).then(networkResponse => {
        return caches.open('app-cache-v1').then(cache => {
          cache.put(event.request, networkResponse.clone());
          return networkResponse;
        });
      });
    })
  );
});
                

오프라인 우선 전략

"오프라인 우선" 패턴은 캐시된 자원이 있으면 이를 먼저 반환하고, 없을 경우 네트워크에서 데이터를 가져와 캐시에 저장하는 방식입니다. 이를 통해 사용자는 인터넷 연결이 없어도 애플리케이션을 사용할 수 있습니다.

업데이트 및 캐시 관리

새로운 버전의 애플리케이션이 배포되었을 때, Service Worker를 업데이트하려면 캐시 이름에 버전 번호를 추가하여 이전 캐시와 구분해야 합니다. 또한, activate 이벤트를 활용해 오래된 캐시를 삭제할 수 있습니다.

결론

이 문서에서는 Service Worker를 사용해 PWA가 오프라인에서도 동작하도록 만드는 방법을 살펴보았습니다. Service Worker는 단순히 오프라인 기능뿐만 아니라 푸시 알림, 백그라운드 동기화 등 다양한 기능을 제공합니다. 이를 통해 사용자 경험을 크게 향상시킬 수 있습니다.