pwa (Progressive Web App) 기초


작년에 w3c 세미나에 운좋게 참여해다가
세상에 웹이 이렇게나 바뀌고 있었나 싶었던 내용을
이제서야 조금 정리해봤다.

PWA(Progressive Web App)

Progressive Web App은 웹의 장점과 앱의 장점을 결합한 환경입니다. 이것은 사용자가브라우저 탭을 맨 처음 방문할 때부터 유용하며, 설치가 필요 없습니다. 시간의 흐름에 따라 사용자가 앱과의 관계를 점진적으로 쌓아갈수록 성능이 더욱 강력해질 것입니다. 이 웹 앱은 느린 네트워크에서도 빠르게 로드되고, 관련된 푸시 알림을 전송하며, 홈 화면에 아이콘이 있고, 최상위의 전체 화면 환경으로 로드됩니다.

모바일웹과 네이티브앱을 비교해보자

웹이 나은점
 - ios, android 두벌로 개발할 필요가 없다.
 - 앱스토어가 필요 없으며 항상 최신버전을 유지할 수 있다.

앱이 나은점
 - 디바이스의 자원을 활용할 수 있다. (카메라, gps 등)
 - push
 - 인터넷이 끊긴 환경에서도 사용이 가능하다.

웹과 앱의 장단점은 명확하지만,
지금의 단말환경에서는
디바이스 자원을 활용할 수 있는 앱이 유리하다.

단, pwa에서는 지금의 웹이 못하는 앱의 장점을 2가지정도는 해결해줄수 있다.
- push, offline

서비스워커(Service-Worker)

pwa에서 가장 핵심요소이다.
현재 크롬,파이어폭스에서는 지원이 가능하며, 사파리와 IE는 개발중이다.
즉, 곧 머지않아 모든 브라우저에서 사용이 가능하다는 뜻이다.
왜?
좋으니까.

구글 개발자사이트에 나온 서비스 워커의 정의는 이렇다

서비스 워커는 브라우저가 백그라운드에서 실행하는 스크립트로, 웹페이지와는 별개로 작동하며, 웹페이지 또는 사용자 상호작용이 필요하지 않은 기능에 대해 문호를 개방합니다. 현재 푸시 알림 및 백그라운드 동기화와 같은 기능은 이미 제공되고 있습니다. 향후 서비스 워커는 주기적 동기화 또는 지오펜싱과 같은 다른 기능을 지원할 것입니다.

하나더 들어가서, 그럼 워커에 대해 간단하게 정리하면

자바스크립트는 기본적으로 단일 스레드로 동작을 한다.
브라우저에서 dom을 렌더링 하는것부터 모든것이 단일스레로 동작을 한다는 뜻인데,
워커는 이와 별개로 백그라운드에서 별도의 실행흐름을 만들어 브라우저의 성능을 더 뽑아먹을 수 있게 해주겠다는 얘기다.
서비스워커는 dom렌더링에 관여하지는 않지만, 네트워크 핸들링을 할 수 있으며 이를기반으로 푸시 이벤트를 지원할 수 있게된다.

서비스워커 예제

- 아래코드를 html페이지에 추가하면 service-worker를 바로 시작할 수 있다.
- service-worker.js 라는 파일을 새로 생성하여 service-worker가 할일을 따로 구현해야한다.
 if ('serviceWorker' in navigator) {
    navigator.serviceWorker
             .register('./service-worker.js')
             .then(function() { console.log('Service Worker Registered'); });
  }

service-worker.js
var cacheName = 'weatherPWA-step-6-1';
var filesToCache = [];
self.addEventListener('install', function(e) {
  console.log('[ServiceWorker] Install');
  e.waitUntil(
    caches.open(cacheName).then(function(cache) {
      console.log('[ServiceWorker] Caching app shell');
      return cache.addAll(filesToCache);
    })
  );
});

install 이벤트는 서비스워커가 최초로 설치됄때 1번 실행된다.
위의 예제에서는 fileToCache라는 배열에 나열된 resource (js,css, image 파일등)들을 저장할 예정이다.
이런식으로 서비스워커에서는 cache기능을 사용해서 인터넷 신호가 약하거나 없는 환경에서도 서비스를 진행할 수 있도록 지원이 가능하다.

서비스워커 생명주기

 - 서비스워커는 dom의 실행과는 별개로 생명주기를 가지고 있다.
 - 설치,설치완료 - 실행 ,실행완료 - 종료
 - 캐시를 사용할때 서비스워커의 특성들을 고려해서 적절한 방법을 모색하여야 한다. 
    (캐시 전략 : https://jakearchibald.com/2014/offline-cookbook/#cache-network-race)



push

서비스워커를 사용해 push를 받을 수 있다.
구글개발자사이트에 있는 예제를 실행해봤다.




왼쪽이 html화면이다 push이벤트를 수신동의/불가 하는 버튼이 있으며
버튼 클릭시 하단에  json형식의 데이터는 구글 테스트 웹 푸시(https://web-push-codelab.glitch.me)
를 보내기위한 파라미터 정보가 표시된다.

오른쪽에는 실행중인 서비스워커를 확인할 수 있다.
if ('serviceWorker' in navigator && 'PushManager' in window) {
  console.log('Service Worker and Push is supported');

  navigator.serviceWorker.register('sw.js')
  .then(function(swReg) {
    console.log('Service Worker is registered', swReg);

    swRegistration = swReg;
    initialiseUI();
  })
  .catch(function(error) {
    console.error('Service Worker Error', error);
  });
} else {
  console.warn('Push messaging is not supported');
  pushButton.textContent = 'Push Not Supported';
}
첫째줄에 serviceWorker외에 pushManager가 추가됨을 확인할 수 있다.
push도 이미 api화 되어있기 때문에 사용하기 어렵지 않아 보인다.

self.addEventListener('push', function(event) {
  console.log('[Service Worker] Push Received.');
  console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);

  const title = 'Push Codelab';
  const options = {
    body: event.data.text(),
    icon: 'images/icon.png',
    badge: 'images/badge.png'
  };

  event.waitUntil(self.registration.showNotification(title, options));
});
서비스워커가 푸쉬이벤트를 감지하게 되면 아래의 코드로 인해 메세지를 노출하게 된다.
생각보다  간단하다.


실제로 메세지를 보내봤다. (https://web-push-codelab.glitch.me)
오른쪽에 알람이 오는것을 확인할 수 있다.




모바일에서도 진행을 해봤는데,
ios의 크롬앱에서는 제대로 동작하지 않았으며,
android의 크롬앱에서는 제대로 동작하는것을 확인할 수 있었다.
ios에서는 아직 지원이 제대로 되고 있지 않은듯 하다.





(글자가 검은색;;)




소감

우선 서비스워커에 대해 학습하는데 어느정도 시간이 걸릴듯하다. 주어진 예제코드를 실행하는데도 쉽게 눈에 들어오지는 않았다. javascript 기초를 조금더 단단하게 할 필요가 있다. 
pwa와 마찬가지로 구글에서 진행하는 amp에서도 service-worker를 지원한다.  (https://ampbyexample.com/components/amp-install-serviceworker/) 조금 더 빠른 모바일 페이지 렌더링을 위해 amp는 이미 어느정도 상용서비스에서 많이 사용하고 있다. pwa와 amp를 적절히 섞어서 사용한다면, 분명 좋은 성능을 낼 수 있을것 같다. 둘다 아직은 기능상 제약이 많지만 어찌됐든 관심을 가져야 할 부분이지 싶다. 

















댓글

이 블로그의 인기 게시물

[spring] log4j 설정 및 사용법

[linux] 백그라운드 작업 nohup [xxx.sh] &

[spring] 인터셉터 와 필터