Service Worker
Caching, Offline, Native Reatures
소개
- 브라우저와 서버 사이의 미들웨어 역할을 하는 스크립트 파일
- PWA에서 가장 중요한 역할을 하고, Offline Experience과 Mobile&Web Push의 기반기술
자바스크립트와의 차이점
chrome://serviceworker-internals/
브라우저에서 돌아가고 있는 서비스워커를 확인할 수 있다.
여기서 inspect 버튼을 클릭하고 콘솔창에this
를 입력해보자.
일반 브라우저에서 this
는 windows를 가리키지만,
서비스워커에서의 this
는 service worker를 가리킨다.
특징
- 브라우저의 백그라운드에서 실행되며 웹페이지와 별개의 라이프 싸이클을 가짐
- Javascript UI 쓰레드랑 별도로 동작하는 또다른 쓰레드
- 네트워크 요청을 가로챌 수 있어 해당 자원에 대한 캐쉬 제공 또는 서버에 자원 요청
- 프로그래밍 가능한 네트워크 프록시
- 브라우저 종속적인 생명주기로 백그라운드 동기화 기능 제공
- Push 알람의 진입점을 제공
- Web&Mobile Push 수신이 가능하도록 Notification 제공
- navigator.serviceworker 로 접근
- 기존 Javascript 와의 별개의 자체 스코프를 가짐
- 크롬 개발자 도구의 Console 과의 별개의 서비스워커 전용 Console 존재
- Dom 에 직접적으로 접근이 불가능 - postMessage() 이용
- 사용하지 않을 때 자체적으로 종료, 필요시에 다시 동작(event-driven 방식)
배경
기존에 이미 존재하던 기술들을 보완 -> 그리고 진화
라이프 싸이클
- 서비스워커는 웹 페이지와 별개의 생명주기
- 서비스워커 등록 & 설치 & 활성화 과정을 잠깐 보면
- 웹페이지에서 서비스워커 스크립트 호출
- 브라우저 백그라운드 에서 서비스 워커 설치
- 설치과정에서 정적 자원 캐싱(Cache 실패시 Install 실패)
- 설치 후 활성화. 네트워크 요청에 대한 가로채기 가능
- 사용하지 않을 때는 휴지 상태. 필요시에만 해당 기능 수행
- 메모리 상태에 따라 자체적으로 종료하는 영리함
등록
- 웹브라우저에 등록
- 브라우저에 존재 유무를 확인 후
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);
});
}
설치
- 캐시를 설치
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);
})
);
});