PWA 만들기

뭐하시는 분이세요?·2022년 6월 17일
0

회사에서 업무용으로 만든 웹페이지를 PWA로 간단히 만들어 배포해보며 알게된 내용을 정리한다.

PWA의 3가지 요건

내가 만든 웹페이지가 PWA로 동작하기 위해서는 아래 3가지 요건을 모두 만족해야한다.

  1. HTTPS 로 운영
  2. manifest 파일이 있어야 함
  3. 서비스워커를 사용해야함

이번 글에서는 2,3 에 대해서 정리해두었다.

manifest

manifest 는 설치, 앱에 관한 구성정보를 담고있는 json 파일이다.
프로젝트 폴더에 manifest.json 파일을 생성하자.

파일 작성하기

{
  "short_name": "프로젝트 이름(아이콘의 이름으로 표시됨)",
  "name": "설치 배너에 표시되는 이름(검색의 키워드로 사용됨)",
  "icons": [
    {
      "src": "favicon.ico",
      "sizes": "64x64 32x32 24x24 16x16",
      "type": "image/x-icon"
    },
    {
      "src": "images/icon192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "images/icon512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "./index.html",
  "display": "standalone",
  "orientation": "portrait",
  "theme_color": "#000000",
  "background_color": "#ffffff"
}
  • icons : 앱에서 필요한 다양한 크기의 아이콘. 앱의 스플래시 화면에서 쓰일 192px이상의 이미지 하나는 꼭 있어야 한다.
  • start_url : 필수요소로, 앱의 스플래시 화면 다음에 나올 페이지의 주소
  • display : 앱이 어떤 모양으로 보여질지 설정하는 값
    - browser(normal) : 해당 브라우저에서 기본 웹으로 실행
    - standalone : 상단의 URL바를 제거. 네이티브처럼 보임(가장 많이 사용함)
    - fullscreen : 화면전체를 사용.
  • orientation : 기기의 방향 (portrait : 세로, landscape : 가로)
  • theme_color : 브라우저 상단의 URL 입력바와 시스템바 까지 포함한 색상
  • background_color : 앱의 배경 색상.

✅ 앱의 스플래시 화면은 background_color + icons + short_name 으로 구성된다.

작성한 manifest 파일을 index.html 에 불러오기

<head> 
	<link rel="manifest" href="manifest.json"> 
</head>

Service worker

서비스워커는 브라우저가 백그라운드에서 실행하는 스크립트로, 웹 과는 별개로 작동한다(웹과 상호작용 불가).

  • 푸시알림, 백그라운드 동기화, 캐싱 등의 기술적 기반이 된다.
  • 도메인 당 서비스워커는 1개만 등록할 수 있다. (1개만 활성화 됨)
  • 웹 브라우저의 기본 fetch 활동을 가로챌 수 있다.

Service worker 의 생명주기

서비스 워커가 활성화 된 상태에서만 푸시알림, Fetch 등을 제어할 수 있다.

1. service worker 등록

먼저, 프로젝트 폴더에 service_worker.js 라는 파일을 만든다.
그리고 index.html 에 연결된 메인 자바스크립트 파일에 service worker를 불러오는 구문을 추가한다.

if('serviceWorker' in navigator) {
  navigator.serviceWorker.register('./service_worker.js').then(() => {
    console.log("서비스워커 등록됨")
  })
}

2. service worker 설치

  • 서비스 워커가 등록되면 설치가 진행됨
  • 오프라인에서 표시할 리소스 캐싱
    - 리소스를 캐싱하는데는 시간이 소요되는데, 이를 event.waitUntil() 메소드를 사용해 기다릴 수 있다.

설치가 완료되면 기존 서비스워커를 사용하는 클라이언트가 완전히 종료될 때 까지 대기하게 된다. (서비스워커 등록과정이면 대기 없이 전환됨)

여기서 self.skipWaiting() 를 사용해 기존 서비스워커 종료를 기다리지 않고 새 서비스워커를 활성화 할 수 있다.

self.addEventListener('install', event => {
    event.waitUntil(...);
});

3. service worker 활성화

  • 이전 서비스워커가 캐싱한 데이터를 지우는 등의 정리작업 수행
    - 마찬가지로 시간이 소요된다면 event.waitUntil() 로 기다릴 수 있음
  • self.clients.claim() 로 열려있는 클라이언트를 다시 로드하지 않고 본 서비스워커가 바로 제어하게 할 수 있음

서비스워커가 활성화 된 이후에는 Functional events 에 해당하는 이벤트를 핸들링하여 조작할 수 있다.(fetch, sync, push)

self.addEventListener('activate', event => {
    event.waitUntil(...);
});

self.addEventListener('fetch', event => {
    event.respondWith(...);
});

전체 코드 한눈에 보기

const cacheName ="cache123456";//캐시 이름 선언. 캐시 리스트 항목이 변경될 때 마다 cacheName을 변경해주어 이전에 사용했던 캐시를 지울 수 있도록 해야한다.
const cacheFiles = ['./','./index.html','./manifest.json', './test.png'];// 캐시할 리소스

//서비스워커 설치하고 캐시파일 저장
self.addEventListener('install', event => {
  event.waitUntil(
      caches
      .open(cacheName)
      .then(cache => {
        // cacheName 에 addAll 메소드로 캐싱할 리소스를 다 넣어줌
        return cache.addAll(cacheFiles);
      })
      .then(() => {
        // 설치 후 바로 활성화 단계로 들어가게 해줌
        return self.skipWaiting();
      })
  );
});

// 서비스워커 작동 시작(활성화)
self.addEventListener('activate', event => {
  event.waitUntil(
    caches.keys().then(key => {
      // 불필요한 캐시는 삭제해줌 (현재 캐시와 이름이 다른 캐시 삭제)
      return Promise.all(key.map(k => {
        if(k !== cacheName) {
          return caches.delete(k);
        }
      }))
    })
  )
});

// 어딘가에서 리소스를 가져올때 실행됨
// 데이터 요청시 네트워크 또는 캐시에서 찾아 반환 
self.addEventListener('fetch', event => {
    event.respondWith(
      caches
      .match(event.request)
      .then(response => {
        // 요청된 내용이 캐시에 있으면 캐싱한 데이터 제공, 아니면 fetch 시킴
        return response || fetch(event.request)
      }).catch(err => 
        console.log(err)
      )
    );
  });


사실 PWA와 서비스워커를 작성하는 방법은 더 다양하고 무궁무진하다.
내가 만든 페이지는 서버가 따로 없어서 푸쉬알림을 보내거나 어떤 요청을 처리하지는 못하지만, 전체적인 컨셉을 이해하고 바로 적용하기 위해 간단히 정리해보았다.

나중에 더 큰 프로젝트를 진행할때 제대로 PWA를 만들어 볼 수 있기를..!! 💨

profile
이것저것 개발하지만 프론트엔드 개발이 제일 좋아요 👩🏻‍💻

0개의 댓글