본문 바로가기

개발/연구

[Service Worker] PWA 기본 등록하고 캐시 다루기

index.html

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<html>
    <head>
 
    </head>
    <body>
        <button id ="click">Click me!</button>
        <div id = "zone" style ="width:500px;word-break: break-all;"></div>
    </body>
    <script>
        var textfile = [];
        window.onload = () =>{
            // 초기 페이지 생성 시 이벤트
            const fileUrl = [
                '/text/1.txt',
                '/text/2.txt',
                '/text/3.txt'
            ];
 
            fileUrl.forEach(element => {
                fetch(element)
                    .then(r => r.text())
                    .then(t => textfile.push(t))
            });
        }
 
        var app = {
            // ES6
            text: '',
            textArea: document.getElementById('zone')
        };
 
        app.showText = function(text){
            // 사용하지 않아도 됨.
            this.textArea.innerHTML = '';
            this.text += text;
 
            this.textArea.innerHTML = this.text;
        }
 
 
        document.getElementById('click').onclick = function(){
            // 클릭 시, 텍스트 하나씩 추가
            console.log("Click");
 
            var node = document.createElement('h');
            var text = '';
            textfile.forEach(element => {
                text += element;
            });
            var textnode = document.createTextNode(text);
            node.appendChild(textnode);
            app.textArea.appendChild(node);
        }
 
        if('serviceWorker' in navigator){
            navigator.serviceWorker.register('service-worker.js').then(() =>{
                console.log('service worker registered');
            });
        }
        
    </script>
</html>
cs

 

service-worker.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const _version = 'v6';
const chacheName = 'v2';
 
const cacheList =[
    '/text/1.txt',
    '/text/2.txt',
    '/text/3.txt',
];
 
const log = msg => {
    console.log(`[ServiceWorker ${_version}] ${msg}`);
}
 
self.addEventListener('install'event =>{
    self.skipWaiting();
    log('INSTALL');
    caches.open(chacheName).then(cache =>{
        log('caching app shell');
        return cache.addAll(cacheList);
    })
});
 
self.addEventListener('activate'event => {
    log('Activate');
  });
  
 
self.addEventListener('fetch'event =>{
    log('Fetch ' + event.request.url);
    event.respondWith(
        caches.match(event.request).then(response =>{
            return response || fetch(event.request);
        })
    );
});
 
// self.addEventListener('fetch', event => {
//   log('Fetch ' + event.request.url);
//   if(event.request.url.indexOf('.jpg')!= -1){
//     event.respondWith(fetch('/images/2.jpg'));
//   }
// });
// 값을 중간에 가로채어, 의도적으로 바꿈
cs

 

 

 

위 소스를 실행한 모습.

파일이 네트워크가 아닌, ServiceWorker에서(캐시에서) 데이터를 가지고 오는 것을 알 수 있다.

오프라인 환경이며, 구동 또한 잘 된다.

 

- 서비스 워커란?

서비스 워커란 DOM과 전혀 독립적인 구조를 띄고 있다고 이해하였습니다. 이는, 환경으로 따지면 Background Process와 유사한 성격을 띔.

브라우저 내에서 서비스 워커가 등록되면 서버와 별개로 사용자의 캐시에 남아 있음.(여기서 브라우저 캐시 메모리 영역에 서비스 워커가 머무릅니다.) 그리고 이에 따라 브라우저 창이 종료되어도 서비스 워커는 동작하고 있음. 이 서비스 워커는 http 통신에서는 허가되지 않으며, https 또는 로컬환경에서 사용이 가능함.

 

- 서비스 워커의 주 사용도

서비스 워커는 위의 언급대로 DOM과 다른, 독립적인 포지션을 취함. 따라서 DOM에 값을 전달할 수 없음. 따라서 외적인 용도로는 사용 목적에 맞지 않음.

그렇지만 서비스 워커는 사용자의 캐시와 소통이 가능함, 이를 테면 인터넷이 끊겼어도 이 전에 남아있던 캐시를 표시해줌으로써 남은 정보(캐시에 저장해두었던 정보)를 출력해주는 것이 가능함.

또한, 서비스 워커는 브라우저 창이 종료되어도 생명주기가 지속 되므로, 푸시를 어렵지 않게 띄울 수 있음.

 

- 서비스 워커 보충 자료

저번 주의 제대로 알지 못한 부분을 조금 더 탐구하였다. 서비스 워커는 백그라운드 프로세스에서 동작하며, PWA(Progressive Web Application)이라고 하는, WebApp의 장점을 동시에 취할 수 있도록 하는 환경에 적합하다.

App에 있는 서비스와 거의 동일한 구조를 띄고 있다. BrowserOS라 생각하고, Browser Cache에 값을 저장할 수 있다. 이렇게 값을 저장하면, 네트워크에서 값을 가져오는 것이 아닌, 캐시에서 가져오기에 네트워크가 꺼진(오프라인) 상태에서도 캐시에 저장된 메모리만으로 웹을 실행시킬 수 있는 것이다.

 

- 서비스 워커 생명주기 및 실습

서비스 워커는 등록, 설치, 활성화, 기능 제어 순으로 생명주기가 있다. 이 생명주기를 토대로 로컬환경에서 서비스 워커를 등록하여, 캐시를 입력하여 오프라인 환경에서도 같은 기능을 수행할 수 있도록 하였다.

 

학습 환경 : Chrome 80.0.3987.163(공식 빌드) (64비트)

 

 

git : https://github.com/kiJu2/PWA-Example