PWA란

윤석찬·2025년 1월 13일
0

What?

PWA의 정의

PWA는 Progressive Web Application의 약자로 웹과 네이티브 앱의 기능 모두의 이점을 갖도록 수 많은 현대 웹 기술을 활용하여 개발된 웹 앱입니다.


When

PWA의 역사

PWA의 역사는 현대 웹 기술의 발전과 함께 시작되었다. 2015년, 구글은 Progressive Web Apps라는 개념을 처음으로 소개하였다. 이는 사용자가 웹 애플리케이션을 네이티브 앱처럼 경험할 수 있도록 만들기 위한 노력의 일환이다. PWA의 개념은 웹의 장점을 최대한 활용하면서도 오프라인에서의 사용성과 빠른 로딩 속도, 그리고 푸시 알림과 같은 기능을 결합하여 사용자 경험을 향상시키는 것을 목표로 한다. PWA의 역사는 이러한 기술이 탄생한 이후 여러 웹 표준과 기술이 결합되면서 발전해왔다. 2016년에는 PWA를 구현하기 위한 서비스 워커와 웹 앱 매니페스트가 공식적으로 W3C의 추천 표준으로 채택되었다. 이로 인해 개발자들은 PWA를 보다 쉽게 구현할 수 있게 되었다. 이후 수많은 기업들이 PWA 기술을 적용하여 웹 애플리케이션을 개발하였고, 사용자들은 이러한 애플리케이션을 통해 더욱 향상된 경험을 누릴 수 있게 되었다. 특히, 2018년에는 여러 유명한 웹사이트와 애플리케이션이 PWA로 전환되면서 그 가능성이 더욱 주목받았다. 현재 PWA는 다양한 플랫폼에서 지원되며, 개발자와 사용자 모두에게 긍정적인 영향을 미치는 기술로 자리 잡았다.


Why

왜 PWA를 사용해야 하는가

웹과 네이티브 앱의 기능 모두의 이점을 모두 가질 수 있기 떄문입니다.

웹의 이점 :

  1. 발견 가능: 컨텐츠를 검색 엔진을 통해 찾을 수 있습니다.
  2. 연결 가능: 간단하게 URL을 전송해 공유할 수 있습니다.
  3. 반응형: 모든 기기의 화면이나 브라우저에서 사용할 수 있습니다. 모바일 폰, 태블릿, 노트북, TV, 냉장고, 등.
  4. 쉬운 동기화: 앱 업데이트가 있을 때 전체를 다시 다운로드 하지 않아도 되고 변경된 컨텐츠만 업데이트 할 수 있음.

네이티브 앱의 이점:

  1. 운영체제와 보다 잘 통합되므로 더 부드러운 사용자 경험을 제공
  2. 네트워크 독립적: 네이티브 앱은 설치되므로써 오프라인이나 불안한 네트워크 연결에서 동작합니다.
  3. 설치 가능: 기기의 홈 화면에서 아이콘을 통하여 쉽게 접근할 수 있습니다.
  4. 재 참여 가능(Re-engageable): 새 컨텐츠가 사용 가능할 때마다 푸시알림을 보낼 수 있습니다.

Who

누가 사용하고 있는가

PWA 라우트를 시도하고 네이티브 앱 보다 더 향상된 웹 사이트 경험을 선택하여 측정 가능한 의미있는 이득을 본 회사들의 성공 스토리가 많습니다. 

  • Flipkart Lite
    2015년에 프로그레시브 웹 앱으로 사이트를 재구축해 전환율을 70% 상승시킨 인도의 가장 큰 전자 상거래 사이트입니다.
  • AliExpress 
    PWA 역시 새로운 사용자에 대한 전환율을 104% 상승시키는 것으로 웹이나 네이티브 앱보다 훨씬 더 나은 결과를 보였습니다. 이윤 증가 및 PWA로 전환을 위해 상대적으로 적은 양의 작업을 놓고 봤을 때, 이점은 분명합니다.

How

어떻게 PWA를 만들 수 있나요?

앱이 위의 요구 사항을 만족하여 다음 기능들이 구현되었을 때 PWA라고 볼 수 있습니다.
(Lighthouse로 자신의 웹앱이 PWA를 만족하는 지 확인할 수 있었지만, 이제 못함…ㅠ)

PWA 개발을 위한 기술 스택

  • ✨서비스 워커(Service Worker): PWA의 오프라인 기능과 푸시 알림을 구현하는 데 필요한 중요한 구성 요소이다. 서비스 워커는 브라우저의 백그라운드에서 작동하며, 네트워크 요청을 가로막고 캐시된 자원을 제공하는 역할을 한다. 이러한 기술 스택을 통해 개발자는 PWA의 성능을 극대화하고, 사용자에게 향상된 경험을 제공할 수 있다.
  • HTML5: PWA의 기본 구조를 만드는 데 필수적인 요소이다. HTML5는 웹 애플리케이션의 콘텐츠와 구조를 정의하며, 다양한 API와 기능을 지원한다.
  • CSS3: 웹 애플리케이션의 스타일과 레이아웃을 관리하는 데 사용된다. CSS3는 반응형 디자인을 적용하여 다양한 화면 크기에 최적화된 사용자 경험을 제공할 수 있다.
  • JavaScript: PWA에 동적인 기능을 추가하는 데 필수적이다. JavaScript는 사용자와의 상호작용을 처리하고, API를 통해 서버와 통신하는 기능을 지원한다.
  • 웹팩(Webpack)과 바벨(Babel)과 같은 모듈 번들러와 트랜스파일러: 이들 도구는 소스 코드를 최적화하고, 다양한 브라우저에서 호환성을 유지하는 데 도움을 준다.

상세 코드

  • 서비스워커 설정 PWA의 구현에서 서비스 워커의 설정은 중요한 단계이다. 서비스 워커는 브라우저와 서버 간의 요청을 가로막아 캐시된 자원을 제공하고, 오프라인 환경에서도 웹 앱이 원활하게 작동할 수 있도록 지원하는 스크립트이다. 서비스 워커는 별도의 파일로 분리되어 웹 앱의 루트 경로에 위치해야 하며, HTTPS 환경에서만 작동한다. 이를 통해 더욱 안전한 웹 환경을 제공한다. 서비스 워커를 설정하는 과정은 일반적으로 다음과 같은 단계로 진행된다.
    • 첫째, serviceWorker.js 파일을 작성 serviceWorker.js 파일이 없다면, src폴더 또는 public폴더 안(FCM은 무조건)에 *생성한다. 만약  template*** 옵션을 사용하거나 이미 serviceWorker파일이 있다면 그 안에 작성하면 된다.
      1. 설치 이벤트를 처리하는 코드

        self.addEventListener("install", event => { // 요청 처리 코드 });
      2. 활성화 이벤트를 처리하는 코드

        self.addEventListener("activate", event => { // 요청 처리 코드 });
      3. fetch 이벤트를 처리하는 코드

        ```jsx
        self.addEventListener(fetch", event => { // 요청 처리 코드 });
        ```

        요청을 가로채고 캐시된 자원을 제공하기 위한 fetch 이벤트를 설정한다. 이 과정에서 와 같은 코드를 사용하여 네트워크 요청을 처리할 수 있다.

      4. push 이벤트를 처리하는 코드

        self.addEventListener("push", function (e) {
          if (!e.data || !e.data.json()) {
            console.error("Push event does not contain valid JSON data.");
            return;
          }
        
          const resultData = e.data.json().notification;
          const resultURL = e.data.json().data.click_action;
        
          if (!resultData || !resultData.title || !resultData.body) {
            const notificationTitle = "Notification data is incomplete.";
            const notificationOptions = {
              body: "Notification data is incomplete.",
            };
            self.registration.showNotification(notificationTitle, notificationOptions);
            return;
          }
        
          const notificationTitle = resultData.title;
          const notificationOptions = {
            body: resultData.body.split("\\n").join("\n"),
            icon: resultData.image,
            tag: resultData.tag,
            data: { click_action: resultURL },
          };
        
          self.registration.showNotification(notificationTitle, notificationOptions);
        });
      5. 웹푸시 클릭 이벤트를 처리하는 코드

        
        self.addEventListener("notificationclick", function (event) {
          const resultURL =
            event.notification.data && event.notification.data.click_action;
        
          if (!resultURL) {
            const notificationTitle = "URL is missing.";
            const notificationOptions = {
              body: "Notification click action URL is missing.",
            };
            self.registration.showNotification(notificationTitle, notificationOptions);
            return;
          }
        
          event.waitUntil(
            clients
              .matchAll({ type: "window", includeUncontrolled: true })
              .then(function (clientList) {
                for (var i = 0; i < clientList.length; i++) {
                  var client = clientList[i];
                  if (client.url === resultURL && "focus" in client) {
                    return client.focus();
                  }
                }
                if (clients.openWindow) {
                  return clients.openWindow(resultURL);
                }
              })
          );
        
          event.notification.close();
        });
        
    • 둘째, 서비스 워커를 등록 먼저 브라우저가 서비스 워커를 지원하는지 확인하고, 지원할 경우 ‘/service-worker.js’ 경로에 있는 서비스 워커 파일을 등록한다. 이를 위해 웹 앱의 메인 스크립트(serviceWorkerRegistration.js) 내에 다음과 같은 코드가 있어야 한다.
      if (‘serviceWorker’ in navigator) { 
      	navigator.serviceWorker.register(/service-worker.js’); 
      }
      만약 다른 serviceWorker(FCM)를 설치하고 싶다면 register내의 serviceWorker.js파일을 바꾸면 된다.
      if (‘serviceWorker’ in navigator) {
      	navigator.serviceWorker.register("./firebase-messaging-sw.js";
      }
  • PWA의 메타 태그 최적화 PWA의 메타 태그 최적화는 검색 엔진 최적화에서 중요한 요소로 작용한다. 메타 태그는 웹 페이지의 정보를 검색 엔진에 전달하는 역할을 하며, 이는 사용자에게 표시되는 결과에 직접적인 영향을 미친다. PWA에서 메타 태그의 올바른 설정은 웹 앱이 검색 결과에서 잘 노출되도록 하는 데 필수적이다. 기본적으로, 메타 태그는 HTML 문서의 섹션에 위치해야 하며, 다음과 같은 주요 메타 태그들이 포함되어야 한다. 첫 번째로, 태그는 페이지의 간략한 설명을 제공하여 검색 엔진이 페이지 내용을 이해하는 데 도움을 준다. 두 번째로, 태그는 모바일 디바이스에서의 사용자 경험을 최적화하는 데 중요하다. 세 번째로, 태그는 PWA의 브랜딩 요소로, 사용자가 앱을 사용할 때 상단 바의 색상을 설정할 수 있다. 이러한 메타 태그들은 PWA의 검색 엔진 가시성을 높이기 위한 필수 요소이며, 이를 통해 사용자 경험을 향상시킬 수 있다. 또한, Open Graph 메타 태그와 같은 소셜 미디어 최적화 메타 태그도 포함할 수 있다. 예를 들어, 와 태그는 소셜 미디어에서 링크가 공유될 때 보여지는 정보를 정의한다. 이들 태그는 PWA가 소셜 플랫폼에서 더 많은 사용자의 클릭을 유도하는 데 기여할 수 있다. 결론적으로, PWA의 메타 태그 최적화는 웹 애플리케이션의 검색 엔진 최적화와 사용자 경험을 개선하는 데 중요한 기여를 한다.
    <!DOCTYPE html>
    <html lang="en">
      <head>
    	  ...
    	  
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta name="theme-color" content="#ffffff" />
        <meta
          name="description"
          content="아주대학교 공지사항 및 이벤트 알림을 받아보세요!"
        />
        <meta content="아주대학교 이벤트 알림 웹앱" property="og:title" />
        <meta content="팀 이쿠죠" property="og:description" />
    
        ...
    </html>
    
  • 웹 앱 매니페스트 구성 PWA 구현에서 웹 앱 매니페스트는 필수적인 요소로, 웹 애플리케이션의 메타데이터를 정의하는 JSON 형식의 파일이다. 이 매니페스트 파일은 애플리케이션의 이름, 아이콘, 시작 URL, 배경 색상, 테마 색상 등 다양한 속성을 포함하여 사용자가 PWA를 설치하고 실행하는 데 필요한 정보를 제공한다. 웹 앱 매니페스트는 사용자 경험을 개선하며, 애플리케이션이 홈 화면에 추가되었을 때의 동작을 정의하는 데 중요한 역할을 한다. 매니페스트 파일은 일반적으로 manifest.json이라는 이름으로 프로젝트의 루트 디렉토리에 위치한다. 다음은 간단한 매니페스트 파일의 예시이다:
    {
      "name": "Witt Web App", // 긴제목
      "short_name": "Witt", // 긴 제목이 표시될 자리가 없을 때 표시되는 짧은 제목
      "description": "카페, 이벤트의 중심이 되다", // 설치시 아래에 나오는 설명
      "icons": [
        {
          "src": "/icons/icon-192x192.png",
          "sizes": "192x192",
          "type": "image/png"
        },
        {
          "src": "/icons/icon-512x512.png",
          "sizes": "512x512",
          "type": "image/png"
        }
      ],
      "start_url": "/",
      "display": "standalone",
      "background_color": "#ffffff", // 앱실행시 로고와 함께 뜨는 로딩 화면의 배경색 설정 
      "theme_color": "#000000" // 앱 상단 바 색깔 설정
    }
    
    이 파일은 PWA가 어떻게 작동하는지를 정의하는 중요한 정보를 담고 있다. 매니페스트 파일은 HTML 문서의 “ 섹션에 링크를 통해 추가해야 한다. 예를 들어, 다음과 같이 추가할 수 있다: 이 설정을 통해 브라우저는 해당 매니페스트 파일을 인식하고, 사용자가 웹 애플리케이션을 설치할 수 있도록 안내한다. 또한, 매니페스트의 속성들은 사용자가 홈 화면에 추가한 애플리케이션이 어떻게 표시될지를 결정하므로, 디자인에 대한 신중한 고려가 필요하다. PWA의 매니페스트 구성은 웹 애플리케이션의 성공에 중요한 요소로 작용하며, 이를 통해 사용자는 보다 나은 경험을 할 수 있다.
  • 아이콘 이미지 추가 애플리케이션이 홈 화면에 추가되었을 때나 실행시켰을 때 보여질 디바이스마다 적절한 크기의 아이콘 이미지들을 추가해야 한다. public폴더 내에 위치하도록 하고, 이 아이콘들은 웹 앱 매니페스트에 선언되어 있어야 한다. png,jpg,webp,svg등

라이브러리 사용

  • react.js

    1. create-react-app로 설정

    create-react-app으로 생성된 프로젝트는 기본적으로 PWA를 지원하며, 서비스 워커를 쉽게 설정할 수 있습니다.

    1.1 create-react-app 설치 (생성된 프로젝트가 없는 경우)

    bash
    코드 복사
    npx create-react-app my-pwa-app
    

    1.2 serviceWorker 활성화

    기본적으로 create-react-app 프로젝트는 src/service-worker.js 파일을 포함하고 있습니다. 이를 활성화하려면 src/index.js 파일에서 serviceWorkerRegistration을 등록해야 합니다.
    1. serviceWorkerRegistration.js 가져오기:

      javascript
      코드 복사
      import React from "react";
      import ReactDOM from "react-dom";
      import "./index.css";
      import App from "./App";
      import * as serviceWorkerRegistration from "./serviceWorkerRegistration";
      
      ReactDOM.render(
        <React.StrictMode>
          <App />
        </React.StrictMode>,
        document.getElementById("root")
      );
      
      // 서비스 워커 등록
      serviceWorkerRegistration.register();
      
    2. src/serviceWorkerRegistration.js는 이미 create-react-app에 포함되어 있습니다.


      1.3 manifest.json 설정

      public/manifest.json에서 다음과 같은 PWA 속성을 설정합니다:

      json
      코드 복사
      {
        "short_name": "ReactPWA",
        "name": "My React Progressive Web App",
        "icons": [
          {
            "src": "icon-192x192.png",
            "sizes": "192x192",
            "type": "image/png"
          },
          {
            "src": "icon-512x512.png",
            "sizes": "512x512",
            "type": "image/png"
          }
        ],
        "start_url": ".",
        "display": "standalone",
        "theme_color": "#000000",
        "background_color": "#ffffff"
      }
      

      Note: 아이콘 이미지를 public 폴더에 추가해야 합니다.

  • next.js
    1. next-pwa 라이브러리 설치

      Next.js 앱을 PWA로 전환하기 위한 플러그인 설치

      npm install next-pwa
      yarn add next-pwa
    2. next.config.js 설정

      next-pwa를 설정하려면 next.config.js에서 구성

      const withPWA = require('next-pwa')({
        dest: 'public', // 서비스 워커 파일을 public 폴더에 생성
        register: true, // 앱 로드 시 서비스 워커 등록
        skipWaiting: true, // 새로운 서비스 워커 설치 시 기존 워커를 대기하지 않고 바로 활성화
      });
      
      module.exports = withPWA({
        reactStrictMode: true,
        // 추가 Next.js 설정이 여기에 포함될 수 있음
      });
    3. manifest.json 생성

      manifest.json은 PWA의 메타정보를 정의하는 파일입니다. 프로젝트의 public 폴더에 생성합니다.

      public/manifest.json:

      {
        "name": "My Next.js PWA",
        "short_name": "NextPWA",
        "description": "This is a Progressive Web App built with Next.js.",
        "icons": [
          {
            "src": "/icons/icon-192x192.png",
            "sizes": "192x192",
            "type": "image/png"
          },
          {
            "src": "/icons/icon-512x512.png",
            "sizes": "512x512",
            "type": "image/png"
          }
        ],
        "start_url": "/",
        "display": "standalone",
        "background_color": "#ffffff",
        "theme_color": "#000000"
      }
    4. 아이콘 추가

      PWA에서 사용할 앱 아이콘을 public/icons 폴더에 저장합니다. 일반적으로 192x192 및 512x512 크기의 PNG 이미지를 포함해야 합니다.

    5. 서비스 워커 테스트

      개발 모드에서는 서비스 워커가 작동하지 않습니다. 프로덕션 빌드 후 테스트해야 합니다.

      npm run build
      npm start

Where

아주대학교 파란학기 프로젝트

https://github.com/AjouEvent

아주대학교 이벤트 알림 웹앱

웹시스템설계 기말프로젝트

번개모임 생성 웹앱 야나와

참고자료

PWA 이점을 나타내는 많은 사례 연구 사이트 : PWA Stats

PWA를 온라인에서 생성 사이트 : PWABuilder

Service worker와 푸시에 관련된 정보 : Service Worker Cookbook

0개의 댓글