웹 앱에서 푸시와 동기화 구현법 서비스 워커 설치 및 활용 2

상세페이지

  • HOME > 월별 특집 & 기획

웹 앱에서 푸시와 동기화 구현법 서비스 워커 설치 및 활용 2

스마트폰에서의 훌륭한 오프라인 경험, 주기적인 백그라운드 동기화, 푸시 알림 등 일반적으로 네이티브 애플리케이션에서 필요로 하는 기능들이 웹에 적용되고 있다.
이 모든 기능이 의존하고 있는 기술적 기반을 제공하는 것이 바로 ‘서비스 워커(Service Worker)’다.
지난 2월호에 설명한 설치법 이후 서비스 워커의 실제 활용법을 알아보자.

이 글은 CC 3.0에 의거, HTML5ROCKS(www.html5rocks.com)와 역자의 허락을 얻고 게재함을 밝힙니다.

원본. Introduction to Service Worker: How to use Service Worker
www.html5rocks.com/en/tutorials/service-worker/introduction

번역본. 서비스워커 소개: 서비스워커는 어떻게 사용하는가
www.html5rocks.com/ko/tutorials/service-worker/introduction



어떻게 캐싱을 수행하고 요청을 반환하는가

설치를 마쳤다면, 이제 여러분은 아마도 캐싱된 응답 중 하나를 반환하고 싶을 것이다. 서비스 워커를 설치하고 사용자가 다른 페이지로 이동하거나 새로 고침을 한 뒤에 서비스 워커는 아래 예제처럼 fetch 이벤트를 받기 시작한다.





이렇게 우리가 정의한 fetch 이벤트와 event.respondWith내에서 caches.match로부터 Promise를 전달한다.
caches.match는 요청을 바라보고 서비스 워커가 생성한 모든 캐시로부터 어떤 캐싱된 결과를 찾아낼 것이다.
만약 알맞은 응답을 가진 상태에서 캐시된 값을 반환한다면, 즉 네트워크 요청을 만들고 네트워크로부터 가져올 수 있는 데이터가 있다면, 데이터를 반환하는 fetch로의 호출 결과를 반환한다. 이는 단순한 예제이고, 설치 단계에서 캐싱한 모든 캐시된 리소스를 사용한다.
만약 새로운 요청들이 누적돼 캐싱되길 원한다면, 아래와 같이 페치(fetch)된 요청에 대한 응답 처리 후 이를 캐시에 추가하는 방법으로 캐싱할 수 있다.






우리가 하고자 하는 것은 다음과 같다. ① fetch 요청 시 .then으로의 콜백 추가

② 응답 수신 후 다음 체크들을 수행한다.
· 유효한 응답인지 확인한다.
· 응답의 상태(status)가 200인지를 확인한다.
· 응답 형식이 기본(basic), 즉 요청이 우리로부터였음을 나타내는지 확인한다. 이는 서드파티 리소스에 대한 요청도 캐싱되지 않음을 의미한다.

③ 체크 사항들을 통과한다면, 응답을 복제한다. 이는 응답이 스트림이고, 바디는 단 한번만 사용할 수 있기 때문이다. 브라우저에서의 사용을 위한 응답 반환과 더불어 사용을 위한 캐시 전달을 원하기 때문에 이를 복제할 필요가 있다. 따라서 하나는 브라우저로, 다른 하나는 캐시로 보낼 수 있다.




어떻게 서비스 워커를 갱신하는가
곧 서비스 워커의 갱신이 필요한 곳이 어디인가가 요점이 된다. 때가 되면, 다음과 같은 단계를 따라야 한다.

① 서비스 워커 자바스크립트 파일을 갱신한다.
· 사용자가 여러분의 사이트를 방문할 때 브라우저는 백그라운드에서 서비스 워커를 정의한 스크립트 파일의 재다운로드를 시도한다. 만약 서비스 워커 파일 내에서 현재 보유 중인 파일과 단 1바이트라도 차이가 존재한다면, ‘새로운 것’으로 간주한다.
② 새로운 서비스 워커가 시작될 것이며 install 이벤트가 발생한다.
③ 현시점에서 기존 서비스 워커가 여전히 현재 페이지를 제어하고 있으므로 새로운 서비스 워커는 ‘대기(Waiting)’ 상태에 들어갈 것이다.
④ 현재 사이트의 열린 페이지들이 닫힐 때, 기존 서비스 워커는 종료될 것이며 새로운 서비스 워커가 제어권을 갖게 된다.
⑤ 새로운 서비스 워커가 제어권을 획득하고 나면 이 서비스 워커의 활성화(Activate) 이벤트가 발생한다.


활성화(activate) 콜백에서 발생할 공통적인 작업 하나는 캐시 관리다. 활성화(activate) 콜백에서 이를 수행하기를 원하게 될 이유는 만약 설치 단계에서 모든 기존 캐시들과 현재의 모든 페이지에 대한 제어권을 유지하고 있는 모든 기존 서비스 워커들을 제거했다면 해당 캐시로부터 파일들을 제공하는 것이 갑자기 중지되기 때문이다.
'my-site-cache-v1'라고 불리는 캐시가 하나 있으며, 이를 페이지들에 대한 캐시 하나와 블로그 포스트들을 위한 캐시 하나로 분리할 필요가 있음을 발견했다고 가정해보자. 이는 설치 단계에서 ‘pages-cache-v1’과 ‘blog-posts-cache-v1’의 두 개의 캐시를 생성하고 활성화(activate) 단계에서 기존 ‘my-site-cache-v1’을 삭제해야 됨을 의미한다.
다음 코드는 서비스 워커 내의 모든 캐시에 대한 루프와 캐시 백서(Whitelist) 내에 정의되지 않은 모든 캐시의 삭제를 통해 이를 수행할 것이다.







Rough Edges & Gotchas
이 개념은 실로 새로운 것이다. 아래에 서비스 워커 활용에 방해되는 이슈 목록이 있다. 이 섹션이 곧 제거될 수 있기를 바라지만 현재로써는 유념할 필요가 있다.


설치가 실패해도 알려주지 않는다
워커가 등록됐지만 chrome://inspect/#service-workers이나 chrome://serviceworker-internals에서 나타나지 않는다면, 이는 event.waitUntil으로 전달된 거부된 프로미스(Rejected promise) 혹은 발생한 에러에 의해 설치에 실패했을 가능성이 있다.
이를 동작하도록 하기 위해서는 chrome://serviceworker-internals으로 가서 ‘Opens the DevTools window for service worker on start for debugging’을 체크하고 서비스 워커의 install 이벤트에 debugger; 문장을 삽입한다. 이는 ‘잡히지 않은 예외에서의 멈춤 기능(Pause on uncaught exceptions, developer.chrome.com/devtools/docs/javascript-debugging#pause-on-uncaught-exceptions)’과 마찬가지로 실제 이슈를 보여준다.


fetch()는 서비스워커 내에서만 가능하다
fetch는 언젠가는 페이지에서 사용이 가능할 것이다. 다만, 현재 크롬에서 구현은 가능하지 않다. 캐시 API 또한 이후 페이지에서 사용 가능하겠지만 현재 캐시는 서비스 워커에서만 사용할 수 있다.


fetch()의 기본 설정들
① 기본으로 제공되는 정보 보호는 없음
fetch를 사용할 때 기본적으로는 요청은 쿠키와 같은 credentials은 포함하지 않는다. 만약 credentials을 사용하고 싶다면 대신 다음 코드를 호출할 수 있다.





이 동작은 의도적인 것이며, 만약 URL이 동일출처(same-origin)라면 credentials를 전송하고 그렇지 않으면 생략하는 XHR의 더 복잡한 기본 설정보다는 틀림없이 나을 것이다. Fetch 동작은 img crossorigin="use-credentials를 통해 사전동의를 하지 않았다면 절대로 쿠키를 보내지 않는 img crossorigin 와 같은 다른 CORS 요청들과 더 유사하다.


② 기본적으로 Non-CORS는 실패한다
기본적으로 서드파티 URL로부터 리소스를 불러오는 것은 만약 CORS를 지원하지 않는다면 실패하게 될 것이다. 여러분은 이를 해결하기 위해 Request에 비-CORS 옵션을 추가할 수 있지만, 이는 응답이 성공인지 실패인지를 알려줄 수 없음을 의미하는 ‘불투명한’ 응답(‘opaque’ response)을 발생시킬 수 있다.





③ fetch()는 30x 리다이렉션 뒤에 동작하지 않는다
불행하게도 리다이렉션은 fetch() 응답 내에서 이어지지 않는다. 이는 다음(code.google.com/p/chromium/issues/detail?id=402389)에서 보다시피 크롬의 버그에 해당한다.




반응형 이미지 다루기

srcset 속성이나 엘리먼트는 실행 중 가장 적합한 이미지 항목을 선택하고 네트워크 요청을 생성할 것이다.
서비스 워커 설치 단계에서 이미지를 캐시하고 싶다면, 다음과 같은 몇 가지 선택사항이 존재한다.
① 엘리먼트와 srcset 속성이 요청할 수 있는 모든 이미지의 설치
② 단일 저해상도 이미지의 설치
③ 단일 고해상도 이미지의 설치


모든 이미지를 내려받는 것은 메모리 낭비일 것이므로 현실적으로 여러분은 2번이나 3번 옵션을 선택해야 한다.
이제 설치 시점에 저해상도 버전을 선택하고 페이지가 로딩되면 네트워크로부터 고해상도 이미지를 가져오기를 시도하는데, 만약 고해상도 이미지를 가져오는 것이 실패하면, 저해상도 버전으로 대체하기로 했다고 가정해보자. 이는 깔끔하고 좋은 방법이지만 다음과 같은 한 가지 문제점이 있다.

다음과 같이 이미지 두 개를 갖고 있다고 가정해보자.

srcset 이미지에서는 다음과 같은 마크업을 가지고 있다.





만약 2× 디스플레이라면 브라우저는 image-2×.png를 내려받을 것이고, 만약 오프라인 상태에서 여러분이 .catch를 통해 이 요청을 잡아 캐시 image-src.png를 반환한다면, 대신 이미지가 캐시됐더라도 브라우저는 2× 스크린 상의 더 많은 픽셀을 가진 이미지를 예상하고 있으므로 이미지는 400×400 CSS 픽셀 대신 200×200 CSS 픽셀처럼 보일 것이다. 이를 해결하기 위한 유일한 방법은 고정 폭과 높이를 이미지에 설정하는 것이다.





아트 디렉션을 위해 엘리먼트를 사용하기 위해, 이 방법는 훨씬 더 어려워질 것이고, 여러분의 이미지가 어떻게 생성되고 사용되는지에 대해 의존적인 상태가 되겠지만, 여러분은 srcset에 대한 유사한 접근 방법을 사용할 수 있다.






URL 해시 변경 관련 버그
Chrome의 구현과 관련해 서비스 워커가 M40 버전에서 URL의 Hash가 변경된 시점 이후로 동작하지 않는 버그가 존재한다.
관련 정보는 code.google.com/p/chromium/issues/detail?id=433708에서 확인할 수 있다.


더 알아보기
jakearchibald.github.io/isserviceworkerready/resources.html에서 관리하고 있는 서비스 워커 관련 문서 리스트를 참고하자.


도움받기
만약 여러분이 서비스 워커 활용 시 어려운 부분이 있다면 Stackoverflow(stackoverflow.com/questions/tagged/service-worker)에 ‘service-worker’ 태그를 달아 질문하자. 가능한 한 더 많은 이슈의 추적과 도움, 시도들을 지속할 수 있을 것이다. 

tags 도창욱 , SK플래닛 , 매니저 , 서비스 워커 , CC 3.0 , HTML5 , HTTPS , API , 인터넷 표준 , 기술

저작권자 © 웹스미디어 무단 전재-재배포 금지

뉴스콘텐츠는 저작권법 제7조 규정된 단서조항을 제외한 저작물로서 저작권법의 보호대상입니다.
본 기사를 개인블로그 및 홈페이지, 카페 등에 게재(링크)를 원하시는 분은
반드시 기사의 출처(로고)를 붙여주시기 바랍니다.
영리를 목적으로 하지 않더라도 출처 없이 본 기사를 재편집해 올린 해당 미디어에 대해서는 합법적인 절차(지적재산권법)에 따라
그 책임을 묻게 되며, 이에 따른 불이익은 책임지지 않습니다.

URL 복사 출력하기 목록보기 스크랩하기

관련기사

최신뉴스
월별 특집 & 기획
웹 앱에서 푸시와 동기화 구현법 서비스 워커 설치 및 활용1
오늘의 뉴스
웨어러블 기술 컨퍼런스 및 전시회 2015 개최
월별 특집 & 기획
웹 앱에서 푸시와 동기화 구현법 서비스 워커 설치 및 활용 2
프로젝트 & 프로모션
SK텔레콤 band LTE 캠페인
월별 특집 & 기획
IT 기술이 교실을 뒤집을 수 있을까? 교실 리뉴얼, 기술은 거들뿐

정기구독신청