싱글 스레드인 JS에서 멀티스레드를 가능하게 해주는 웹 기술이다.
WebWorker는 브라우저 백그라운드 환경에서 동작하며 스레드간 통신을 통해서 제어할 수 있다.
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Service Worker</title>
</head>
<body>
<button id="hi">say Hi</button>
<button id="unknownCMD">Send unknown command</button>
<button id="stop">Stop Worker</button>
<div id="result"></div>
<div id="service"></div>
<script src="/service.js"></script>
</body>
</html>
// main page
// worker.js
const $hi = document.querySelector('#hi');
const $unknownCMD = document.querySelector('#unknownCMD');
const $stop = document.querySelector('#stop');
const $result = document.querySelector('#result');
// webWorker 생성
var worker = new Worker('task.js');
$hi.addEventListener('click',()=>{
// worker와의 통신은 postMessage을 통해서 한다.
worker.postMessage({
'cmd':'start',
'msg':'hi',
})
});
$unknownCMD.addEventListener('click',()=>{
worker.postMessage({
'cmd':'???',
'msg':'unknown'
});
});
$stop.addEventListener('click',()=>{
worker.postMessage({
'cmd':'stop',
'msg':'bye',
});
});
worker.addEventListener('message',function(msg){
$result.innerHTML = msg.data;
});
//task.js
//web worker
//worker 내에서 다른 스크립트를 import 할대에 사용하는 함수이다.
importScripts('workerScripts.js');
//self, worker을 의미한다.
self.addEventListener('message',function(e){
importedFunction();
switch(e.data.cmd){
case 'start':
self.postMessage('start');
break;
case 'stop' :
self.postMessage('stop');
self.close();
break;
default:{
self.postMessage('unknown Message');
}
}
},false);
대부분 CPU 작업이 많이 필요한 경우 Worker을 사용하여 처리한다.
WebWorker의 일종으로 푸시, 백그라운드 동기화, 응답 캐싱과 같은 기능을 제공하기 위해서 탄생한 웹 기술
Service Worker는 놀랍게도 오프라인 상태에서도 웹 어플리케이션을 사용할 수 있게 하는 기술이다.
PWA 앱을 만드는데 이용되는 기술이다.
브라우저에서 보내는 요청을 가로채 미리 캐싱된 데이터를 보내는 기능을 제공한다.
Service Worker는 브라우저창이 닫힌 상태에서 동작한다. 마치 네이티브 앱처럼 Push 알람을 주는것이 가능하다.
작업을 수행하던 도중 인터넷이 끊겼을 때 현재까지 작업 내용을 저장해둔후 인터넷이 연결될때 저장해둔 내용을 서버로 보내는것이 가능하다.
서비스 워커를 사용하기 위해서는 브라우저에 등록하여야 한다.
브라우저는 서비스 워커가 존재하지 않다면 해당 서비스 워커를 백그라운드에 등록한다.
등록하기전에 서비스 워커에서 사용될 정적 데이터들을 모두 캐싱해두는데 만약 하나라도 캐싱에 실패하면 서비스 워커는 등록되지 않는다.
등록된 서비스 워커는 Activated 상태가 되고 사용하지 않는다면 Idle 상태로 들어간다.
Idle 상태에서 서비스 워커는 메모리를 절약하기 위해 종료되거나, 네트워크 이벤트나 Message가 생성되면 해당작업을 처리하게 된다.
//서비스 워커 등록
// service.js
if('serviceWorker' in navigator){
window.addEventListener('load',()=>{
navigator.serviceWorker.register('/sw.js').then(function(registration){
console.log('ServiceWorker registration successful with scope: ',registration);
},function(err){
console.log('ServiceWorker registration failed: ',err);
});
});
}
// sw.js
const CACHE_NAME = 'my-site-cache-v1';
const urlsToCache = [
'/',
'/styles/main.css',
'/script/main.js',
'/hi',
];
self.addEventListener('install',function(event){
console.log('install');
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache){
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
self.addEventListener('fetch', function(event) {
if(event.request.url === 'http://localhost:3000/hi'){
return event.respondWith(
new Response(JSON.stringify({
"data":"bye"
}), {
headers: { 'Content-Type': 'application/json' }
})
)
}
console.log('here?');
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit - return response
if (response) {
console.log(response);
return response;
}
return fetch(event.request);
}
)
);
});
서비스 워커는 도메인을 바탕으로 동작한다.
현재 서비스워커는 만약 서비스워커 파일이 /example/sw.js라면
/example로 시작하는 URL 페이지에서만 fetch 이벤트를 처리하는게 가능하다.
https://medium.com/@siobhanpmahoney/a-brief-introduction-to-web-workers-e5d6e39d9d28
https://www.html5rocks.com/en/tutorials/workers/basics/
https://developes.google.com/web/fundamentals/primers/service-workers/?hl=ko