Service Worker

Caching, Offline, Native Reatures

소개

  • 브라우저와 서버 사이의 미들웨어 역할을 하는 스크립트 파일
  • PWA에서 가장 중요한 역할을 하고, Offline Experience과 Mobile&Web Push의 기반기술

자바스크립트와의 차이점

chrome://serviceworker-internals/ 브라우저에서 돌아가고 있는 서비스워커를 확인할 수 있다. 여기서 inspect 버튼을 클릭하고 콘솔창에this를 입력해보자. 일반 브라우저에서 this는 windows를 가리키지만, 서비스워커에서의 this는 service worker를 가리킨다.

특징

  1. 브라우저의 백그라운드에서 실행되며 웹페이지와 별개의 라이프 싸이클을 가짐
    • Javascript UI 쓰레드랑 별도로 동작하는 또다른 쓰레드
  2. 네트워크 요청을 가로챌 수 있어 해당 자원에 대한 캐쉬 제공 또는 서버에 자원 요청
  3. 브라우저 종속적인 생명주기로 백그라운드 동기화 기능 제공
    • Push 알람의 진입점을 제공
  4. Web&Mobile Push 수신이 가능하도록 Notification 제공
  5. navigator.serviceworker 로 접근
  6. 기존 Javascript 와의 별개의 자체 스코프를 가짐
    • 크롬 개발자 도구의 Console 과의 별개의 서비스워커 전용 Console 존재
  7. Dom 에 직접적으로 접근이 불가능 - postMessage() 이용
  8. 사용하지 않을 때 자체적으로 종료, 필요시에 다시 동작(event-driven 방식)

배경

기존에 이미 존재하던 기술들을 보완 -> 그리고 진화

라이프 싸이클

  • 서비스워커는 웹 페이지와 별개의 생명주기
  • 서비스워커 등록 & 설치 & 활성화 과정을 잠깐 보면
    1. 웹페이지에서 서비스워커 스크립트 호출
    2. 브라우저 백그라운드 에서 서비스 워커 설치
    3. 설치과정에서 정적 자원 캐싱(Cache 실패시 Install 실패)
    4. 설치 후 활성화. 네트워크 요청에 대한 가로채기 가능
  • 사용하지 않을 때는 휴지 상태. 필요시에만 해당 기능 수행
  • 메모리 상태에 따라 자체적으로 종료하는 영리함

등록

  • 웹브라우저에 등록
  • 브라우저에 존재 유무를 확인 후 register()사용
  • index.html 같은 레벨에 sw.js 파일(서비스 워커 스크립트 파일)을 만들고 index.html 안에 아래의 코드를 입력한다.
  • 서비스워커의 위치는 주 도메인과 같은 위치에 있어야 합니다.
if ('serviceWorker'  in  navigator) {
	navigator.serviceWorker.register('sw.js')
	.then(function (reg) {
		console.log('service worker 등록완료', reg);
	})
	.catch(function (err) {
		console.log('service worker 등록실패', err);
	});
}

then? catch? - Promise

설치

  • 캐시를 설치
  • register()에서 등록한 스크립트 파일(sw.js)에서 install()호출
  • CACHE_NAME : 캐쉬를 담을 파일명 정의
  • filesToCache : 캐쉬할 웹 자원들 정의
  • waitUntil() : 안의 로직이 수행될 때 까지 대기
// 캐싱 스토리지에 저장될 파일 이름
var  CACHE_NAME  =  'pwa-offline-v1';
// 캐싱할 파일 목록
var  filesToCache  = [
	'/',
	'/css/app.css'
];
// 서비스 워커 설치 (웹 자원 캐싱)
self.addEventListener('install', function(event) {
	//캐쉬 등록 또는 기타 로직 수행
	event.waitUntil(
		caches.open(CACHE_NAME)
		.then(function(cache) {
			// 위에 지정한 캐쉬 목록을 'pwa-offline-v1' 캐쉬에 추가
			return  cache.addAll(filesToCache);
		})
		.catch(function(error){
			return  console.log(error);
		})
	);
});

-주의 : 캐쉬할 파일 중 한개라도 실패하면 전체 실패. 이를 해결하기 위해 sw-toolbox 사용 가능

네트워크 요청 응답

  • 서비스워커 설치 후 캐쉬된 자원에 대한 네트워크 요청이 있을 때는 캐쉬로 돌려준다.
  • responWith() : 네트워크 요청 가로채기 및 캐쉬 응답
  • match(): 해당 request에 상응하는 캐쉬가 있으면 찾아서 돌려주고 아니면 fetch()로 자원획득
  • 개발자도구 Network 패널의 offline 체크 후 캐쉬응답 확인
self.addEventListener('fetch', function(event){
	event.respondWith(
		caches.match(event.request)
		.then(function(response){
			return  response  ||  fetch(event.request);
		})
		.catch(function(error){
			return  console.log(error);
		})
	);
});

활성화 및 업데이트

  • 새로운 서비스워커가 설치되면 활성화 단계로 넘어온다.
  • 이전에 사용하던 서비스워커와 이전 캐쉬는 모두 삭제하는 작업진헹
self.addEventListener('activate', function(event) {
	var  cacheWhitelist  = ['v2'];
	event.waitUntil(
		caches.keys()
		.then(function(keyList) {
			return  Promise.all(
				keyList.map(function(key) {
					if (cacheWhitelist.indexOf(key) ===  -1) {
						return  caches.delete(key);
					}
				})
			);
		})
		.catch(function(error){
			return  console.log(error);
		})
	);
});