icon안동민 개발노트

PWA (Progressive Web App) 설정


 Next.js App Router 애플리케이션을 Progressive Web App (PWA)으로 변환하는 것은 성능 향상과 사용자 경험 개선에 큰 도움이 됩니다.

 이 절에서는 PWA의 주요 특징과 Next.js에서 PWA를 구현하는 방법에 대해 알아보겠습니다.

PWA의 주요 특징

  1. 오프라인 작동
  2. 빠른 로딩 속도
  3. 푸시 알림
  4. 홈 화면에 추가 가능
  5. 네이티브 앱과 유사한 사용자 경험

next-pwa 라이브러리 설정

  1. 설치
npm install next-pwa
  1. next.config.js 수정
next.config.js
const withPWA = require('next-pwa')({
  dest: 'public',
  disable: process.env.NODE_ENV === 'development',
})
 
module.exports = withPWA({
  // 다른 Next.js 설정
})

매니페스트 파일 생성

 public/manifest.json 파일 생성

public/manifest.json
{
  "name": "My Next.js PWA",
  "short_name": "Next PWA",
  "description": "A Progressive Web App built with Next.js",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#000000",
  "icons": [
    {
      "src": "/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

서비스 워커 설정

 next-pwa는 자동으로 서비스 워커를 생성합니다.

 경우에 따라 커스텀 서비스 워커가 필요한 경우, public/sw.js 파일을 생성하여 커스텀 로직을 추가할 수 있습니다.

 1. public/sw.js 파일 생성

public/sw.js
self.addEventListener('install', (event) => {
  console.log('Service Worker installed');
});
 
self.addEventListener('activate', (event) => {
  console.log('Service Worker activated');
});
 
self.addEventListener('fetch', (event) => {
  console.log('Fetch intercepted for:', event.request.url);
});

 2. next.config.js 수정

next.config.js
const withPWA = require('next-pwa')({
  dest: 'public',
  disable: process.env.NODE_ENV === 'development',
  register: true,
  skipWaiting: true,
  sw: '/sw.js'
})
 
module.exports = withPWA({
  // 다른 Next.js 설정
})

오프라인 기능 구현

  1. 오프라인 페이지 생성 (pages/offline.js)
pages/offline.js
export default function Offline() {
  return <h1>You are offline. Please check your internet connection.</h1>
}
  1. 서비스 워커에서 오프라인 페이지 캐싱
const CACHE_NAME = 'offline-cache-v1';
const OFFLINE_URL = '/offline';
 
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => cache.add(OFFLINE_URL))
  );
});
 
self.addEventListener('fetch', (event) => {
  if (event.request.mode === 'navigate') {
    event.respondWith(
      fetch(event.request).catch(() => caches.match(OFFLINE_URL))
    );
  }
});

푸시 알림 설정

  1. 웹 푸시 라이브러리 설치
npm install web-push
  1. VAPID 키 생성
npx web-push generate-vapid-keys
  1. 서버 측 푸시 알림 처리 (pages/api/subscribe.js)
pages/api/subscribe.js
import webPush from 'web-push';
 
webPush.setVapidDetails(
  'mailto:[email protected]',
  process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY,
  process.env.VAPID_PRIVATE_KEY
);
 
export default async function handler(req, res) {
  if (req.method === 'POST') {
    const subscription = req.body;
    try {
      await webPush.sendNotification(subscription, JSON.stringify({
        title: 'Hello from Next.js',
        body: 'This is a push notification!',
      }));
      res.status(200).json({ success: true });
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  } else {
    res.setHeader('Allow', 'POST');
    res.status(405).end('Method Not Allowed');
  }
}
  1. 클라이언트 측 푸시 알림 구독
async function subscribeToPushNotifications() {
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY,
  });
 
  await fetch('/api/subscribe', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(subscription),
  });
}

12장 성능 최적화와의 연관성

 PWA 구현은 12장에서 다룬 성능 최적화와 밀접하게 연관됩니다.

 서비스 워커를 통한 자원 캐싱은 로딩 속도를 크게 향상시키며, 오프라인 기능은 네트워크 상태와 관계없이 일관된 사용자 경험을 제공합니다.

 또한, PWA의 "설치 가능" 특성은 반복 사용자의 참여도를 높이고 성능을 개선합니다.

실습 : Next.js 앱을 PWA로 변환

 기존 Next.js App Router 애플리케이션을 PWA로 변환하고, 오프라인 기능과 푸시 알림을 구현해보세요.

  1. next-pwa 설치 및 설정
  2. 매니페스트 파일 생성
  3. 오프라인 페이지 구현
  4. 푸시 알림 기능 추가

 단계별 가이드

 1. next-pwa 설치 및 설정

  • npm install next-pwa 실행
  • next.config.js 파일 수정 (위의 예제 참조)

 2. 매니페스트 파일 생성

  • public/manifest.json 파일 생성 (위의 예제 참조)
  • 필요한 아이콘 파일들을 public 폴더에 추가

 3. 오프라인 페이지 구현

  • app/offline/page.js 파일 생성
  • 서비스 워커 파일 (public/sw.js) 수정하여 오프라인 페이지 캐싱 추가

 4. 푸시 알림 기능 추가

  • VAPID 키 생성
  • 서버 측 API 라우트 생성 (app/api/subscribe/route.js)
  • 클라이언트 측 구독 로직 구현 (예 : 버튼 클릭 시 구독)

 5. 테스트

  • 개발 서버 실행 및 브라우저에서 애플리케이션 열기
  • Lighthouse를 사용하여 PWA 점수 확인
  • 오프라인 모드에서 애플리케이션 동작 테스트
  • 푸시 알림 구독 및 수신 테스트

 이 실습을 통해 Next.js App Router 애플리케이션을 완전한 PWA로 변환하는 과정을 경험할 수 있습니다.

 PWA 구현은 웹 애플리케이션의 성능을 크게 향상시키고 사용자 경험을 개선하는 강력한 방법입니다.

 오프라인 기능, 푸시 알림, 빠른 로딩 속도 등의 특징은 사용자 참여도를 높이고 애플리케이션의 가치를 증대시킵니다.

 Next.js와 next-pwa를 활용하면 이러한 고급 기능을 비교적 쉽게 구현할 수 있으며, 이는 현대적인 웹 개발의 중요한 부분입니다.