Skip to main content

· 8 min read
이현진

다크모드를 켜주세요!

안녕하세요 저희는 이현진, 김시온, 유찬희로 이루어진 야자(야간자율학습)팀입니다.

MOZI는 할 일 관리 서비스입니다.

모지 -> MOZI

생산성 분야에서 유명한 책인 David Allen의 Getting Things Done이라는 책에서 사람들은 무엇이든 할 수는 있지만, 모든 것을 할수는 없다고 말합니다. 모든 것을 하기위해 할 일을 기록하는 것은 필수적입니다.

MOZI에서는 사람들이 할 일을 관리하는 방식에 집중했습니다.

기획 단계에서 97명의 참여자를 대상으로 사람들이 할 일을 관리하는 방식을 조사했습니다.

먼저 주로 어떤 것을 메모하는지 물어봤습니다.

대다수의 사람들이 일정 관리를 하기위해 메모를 작성하고 있었고 장보기 목록, 갑자기 떠오른 아이디어, 계정 비밀번호 저장, 맛집 리스트가 뒤를 이었습니다.

이를 그룹화해서 분류해보면 시간에 관한 메모, 장소에 관한 메모, 시간과 장소모두 관련된 메모로 분류할 수 있었습니다.

저희는 시간과 장소라는 키워드에 주목해봤습니다. 사람들이 원하는 할 일 관리 애플리케이션은 정해진 시간에 할 일을 할 수 있도록 도와줘야합니다. 또한 정해진 장소에서 어떤 할 일을 해야하는지 시각화해서 보여줄 수 있어야합니다.

정해진 시간에 할 일을 하기위해 알림 기능이 필요합니다. 정해진 장소에서 해야하는 일을 확인하려면 지도에 할 일을 표시할 수 있어야합니다.

이 두가지 기능을 핵심으로하여 MOZI를 만들었습니다.

기존의 서비스에서 시간과 장소에 집중하여 서비스를 만들기로 했습니다.

먼저 저희가 고려한 시간 부분입니다.

"할 일을 메모해뒀지만 잊어버린 경험이 있으신가요?"라는 설문에 72%의 사람들이 할 일을 메모해뒀지만 까먹은 경험이 있다고 답변하였고 이를 해결하기 위해 각각의 할 일에 대한 알림 기능을 만들었습니다.

할 일에 대해서 알림 시간DeadLine을 설정하여 알림이 와야하는 시간과 할 일을 끝내야하는 날짜를 설정하여 관리할 수 있도록 구현했습니다.

설정한 시간을 바탕으로 캘린더에 시각화해서 보여주고 그 시간이 되면 정해진 내용으로 알림이 오도록 했습니다.

다음으로 할 일을 지도에 등록할 때 고려한 부분입니다. 할 일을 지도에서 클릭을 통해 쉽게 등록할 수 있도록 구현했습니다.

또한 알림을 받을 범위를 설정할 수 있도록 해서 원하는 범위 내부에서만 알림을 받을 수 있도록 구현했습니다.

지도에서 검색을 할 경우 사용자가 원하는 장소로 쉽게 이동할 수 있고 해당 검색 기록은 저장되어 추후에 그 장소로 빠르게 이동할 수 있도록 했습니다.

장소와 관련하여 사람들에게 더 좋은 경험을 제공하기 위해 현재 위치를 기반으로 장소를 추천해주는 기능을 추가했습니다. 추천되는 장소는 현재 위치에서 가까운 유동인구가 많은 유명한 장소입니다. 사용자는 여행이나 맛집 탐방을 진행할때 해당 기능을 사용하여 유명한 장소를 쉽게 찾아 할 일을 등록할 수 있습니다.

다음으로 각각의 할 일에 대하여 알림을 받고 싶은 조건을 설정할 수 있도록 했습니다. 시간 알림이나 장소 알림 중 원하는 알림만 받을 수 있으며 시간과 장소 모두 만족하는 조건에 대한 알림을 설정할 수도 있습니다.

MOZI와 같은 할 일 관리 애플리케이션은 시간과 장소에 관계없이 접근가능해야합니다. 예를 들어 밖에서 핸드폰을 하고 있는 중에도 접근가능해야하고, 업무중에 데스크탑에서도 접근할 수 있어야합니다. 심지어는 비행기와 같이 네트워크가 정상적으로 작동하지 않는 상황에서도 접근할 수 있어야합니다.

따라서 저희는 MOZI를 어디서든지 접근할 수 있게 만들기 위해 노력했습니다.

어떠한 상황에서도 애플리케이션을 항상 사용 가능한 상태로 만들기 위해 두가지 상황을 고려했습니다.

첫째로 어떤 기기에서도 접근 가능해야한다. 둘째로 오프라인 상황에서도 사용할 수 있어야한다.

다양한 기기를 지원하려면 안드로이드와 iOS, 즉 네이티브 애플리케이션을 따로 개발해야하며, 웹도 만들어야합니다.

모든 플랫폼에 맞는 애플리케이션을 개발할 수는 없기에 코드를 한번 작성하고 모든 플랫폼을 지원할 수 있는 전략을 채택했습니다.

바로 PWA를 활용하는 것 입니다.

웹과 네이티브 앱을 각각 개발하는 대신에 웹의 장점을 극대화한 PWA를 활용하였습니다.

PWA는 웹에서 네이티브 앱의 경험을 느낄 수 있도록 합니다.

웹에서 설치가능하도록 할 수 있어서 앱스토어를 거치지 않고 핸드폰이나 데스트탑에 바로 설치할 수 있습니다.

다음으로 고려한 사항은 오프라인 지원입니다. PWA도 웹이기 때문에 웹의 한계에 종속될 수 밖에 없습니다.

웹의 한계는 다음과 같습니다. 웹 브라우저에서 서버가 연결되어있어야만 동작할 수 있다는 것입니다. 데이터를 수정하려면 서버에 요청을 해야합니다.

네트워크의 연결이 끊어진다면 아무것도 할 수 없습니다.

이 네트워크라는 한계에 종속되지 않게 하기 위하여 브라우저에 존재하는 데이터베이스인 IndexedDB를 데이터 통신의 기점으로 사용했습니다. 브라우저에서 유저의 모든 상호작용이 IndexedDB에 저장이되고 네트워크 연결이 되어있으면 서버에 바로 동기화 시킵니다.

네트워크 연결이 끊어졌을 경우에는 네트워크 연결이 다시 이루어졌을 때 브라우저의 Sync Manager가 네트워크 연결을 감지하고 사용자가 오프라인에서 했던 작업들을 서버에 동기화 시킵니다.

이를 백그라운드 동기화라고 합니다. 백그라운드 동기화를 통해 기존 웹의 한계를 넘을 수 있습니다. 사용자는 네트워크 연결과 관계없이 웹과 상호작용할 수 있습니다. 또한 오프라인에서 했던 작업들이 온라인에 잘 동기화되었는가 신경쓸 필요가 없습니다.

이렇게 저희가 겪었던 두가지 문제를 모두 해결했습니다. 여러 플랫폼을 지원해야하는 문제를 PWA를 사용하여 코드를 한번 작성하는 것으로 해결했습니다. 오프라인에서도 작동해야하는 문제를 백그라운드 동기화 기능을 사용하여 해결했습니다.

할 일 관리 서비스는 정말 다양하고 많습니다. MOZI에서는 브라우저의 장점을 최대한 살려 백그라운드 동기화를 통한 오프라인 기능과 알림 기능을 구현했습니다.

할 일관리를 시간과 장소에 특정해 접근했다는점,
애플리케이션을 어디서든 쉽게 사용할 수 있다는점이 저희가 진행한 프로젝트의 가치라고 생각합니다.

기존 David Allen의 인용문을 확장하면, 사람들은 무엇이든 할 수는 있지만 모든 것을 어디에서나, 언제나 할 수는 없습니다.

감사합니다.

· 2 min read
이현진

Push API는 웹 애플리케이션이 현재 로딩이 되어 있지 않더라도 서버로부터 메시지를 받을 수 있도록 하는 기능이다. 이는 개발자들이 비동기적으로 사용자에게 새로운 내용을 시기적절하게 전달할 수 있도록 만들어줍니다.

Web Push의 가장 큰 문제점은 사파리 브라우저에서 지원하지 않는 API가 여럿 있다는 것인데, WWDC22의 Meet Web Push for Safari 세션에서도 웹 푸쉬에 관한 내용이 언급되었습니다.

Web Push is supported in Mac Safari beginning with macOS Ventura. And Web Push will be coming to iOS and iPadOS next year.

애플리케이션이 push 메시지를 받기 위해서, service worker를 활성화합니다.

PushSubscription에 애플리케이션이 보내야하는 push 메시지를 담고,(엔드 포인트와 암호화키가 필요) service worker는 ServiceWorkerGlobalScope.onpush()라는 이벤트 핸들러로부터 전달되는 push 메시지를 처리하기 시작합니다.

각 요청은 capability URL:(당신이 애플리케이션)을 특정하여 엔드포인트를 구성하기 때문에 URL은 보안에 신경을 써야하며, 그렇지 않을 경우 다른 애플리케이션이 당신의 애플리케이션에 push 메시지를 보낼 가능성도 있다.

push 메시지를 전달하기 위해 service worker를 활성화하는건, 리소스 사용이 늘어나는 결과를 가져오기 때문에, 특히 배터리 사용에 영향을 미칩니다. 한편 push 메시지 처리를 위해 브라우저 간 다른 스키마를 가지기 때문에, 표준화된 메커니즘이 없습니다.

Reference

· 2 min read
이현진

SEO란?

SEO란 Search Engine Optimization의 약자로 웹에 올리는 컨텐츠가 구글, 네이버, 다음과같은 검색엔진으로부터 제대로 인식이 될 수 있도록 최적화하는 작업이다. 최적화하는 방법에는 양질의 콘텐츠를 제공하거나, 접근성이나 성능적으로 뛰어난 웹을 개발하는 방법 등이 있지만 가장 기본적인 방법으로는 해당 페이지에 적합한 메타 태그를 삽입해서 크롤러가 웹을 잘 분석해서 인덱싱 하는데 도움을 주는 방법이 있다.

· 12 min read
이현진

이번 글에서 다뤄볼 주제는 PWA입니다.

PWA라는 용어는 Progressive Web App의 약자입니다. 이 용어는 이제 많이 퍼져서 많은 사람들이 사용하고 있습니다. 하지만 PWA라는 용어를 쓰는 사람마다 사용하는 기능이 무엇인지에 따라 그 의미가 종종 바뀌기도 합니다.

· 6 min read
이현진

프론트엔드 모니터링이란

프론트엔드 모니터링은 웹 사이트 또는 앱의 성능을 추적하는데 사용되는 일련의 프로세스 및 도구입니다. 프론트엔드 모니터링은 주로 사용자가 최종적으로 보는 부분에 중점을 둡니다. 여기에는 다음과 같은 문제가 포함됩니다.

· 5 min read
이현진

MOZI에서는 할 일을 드래그 앤 드롭을 통해 수정할 수 있어야한다.(예를 들어 할 일 복원) 어떻게 보면 스토리에서 우선순위는 아니였기에 뒤로 미루다가 벨로그에서 좋은 글을 발견하고 글에 나와있는 프로젝트를 그대로 구현해보면서 배우기로 했다.

· 5 min read
이현진

MOZI에는 Upcoming이라는 탭이 존재합니다. 이 탭에서는 다가오는 할 일을 볼 수 있고 할 일을 등록할 수 있습니다.

3_Upcoming

이 글은 위 화면과 같이 달력을 만들어보면서 겪은 경험을 기록한 글입니다.

· 13 min read
이현진
스크린샷 2022-09-29 오전 12 11 04

Thinking in React(React로 생각하기)라는 주제로 발표를 진행하겠습니다. React로 생각한다는 표현이 조금 추상적일 수 있는데, 이 발표에는 React를 다룰 때 갖고 있어야하는 생각들을 담았습니다.

· 13 min read
이현진

Intro

소프트웨어 마에스트로 컨퍼런스 발표(8.31) 내용을 요약한 글 입니다.

안녕하세요. 소프트웨어 마에스트로 연수생 이현진입니다.

이번 발표에서는 GraphQL의 컨셉, REST API와의 차이, 실제 활용 실습과 더 나아가 React에서 GraphQL이 해결할 수 있는 문제에 대해서 이야기해보도록 하겠습니다.

· 13 min read
이현진

서비스 워커는 브라우저가 백그라운드에서 실행하는 스크립트로, 웹 페이지와는 별개로 작동하며 웹 페이지 또는 사용자의 인터랙션이 필요하지 않은 기능만 제공하고 있다. 서비스 워커의 수명주기는 웹 페이지와는 완전히 별개이다. 웹 서비스와 브라우저 및 네트워크 사이에서 프록시 서버 역할을 하며, 오프라인에서도 서비스를 사용할 수 있도록 한다.

웹 페이지와 별개로 존재하기 때문에 다음과 같은 제약이 있다.

  1. 서비스 워커는 요청하지 않는 이상, 없는 것이나 다름이 없다.
  2. 웹 페이지 life cycle을 따르지 않는다. 서비스 워커는 웹 페이지가 닫히더라도 자동으로 비활성화되지 않는다.
  3. 웹 페이지와 별개로 존자해므로 DOM이나 window 요소에 접근할 수 없다.

캐시와 상호작용

image

fetch 이벤트의 중간자 역할로 사용할 수 있다. 이 경우 서비스 워커는 HTTP를 통해 정보를 요청하는 대신 가지고 있는 캐시에서 자료를 전달한다. 캐시가 삭제되지 않는 한 브라우저는 인터넷 연결 없이도 정보를 보여줄 수 있다.

푸쉬 알림

image

브라우저 창이 닫힌 상태에서도 동작하므로, 푸시 알림을 구현할 수 있다.

백그라운드 동기화

image

채팅 메시지 또는 사진 업로드 등의 작업 도중 컴퓨터가 오프라인 상태가 되는 경우 온라인 상태가 되었을 때 해당 작업을 마저 완료할 수 있다.

Fetch

fetch란 web resource에 접근하기 위해 행해지는 모든 request action을 의미한다. service worker는 fetch를 통해 발생하는 모든 http request를 중간에서 가로챌 수 있다. (proxy) 예를 들어 실 서버로 보내지는 request를 중간에서 가로채어 서버로 보내지 말고 대신 cache 된 데이터를 제공하는 등의 처리를 하는 것이 가능하다.

http request가 있을 때마다 fetch이벤트가 발생하는데 service worker는 fetch event listener를 등록하여 이벤트를 감지하고 있다가 fetch이벤트가 발생할 때 listener에서 request를 intercept하는 방식이다.

메시지를 통한 서비스 워커와 페이지간의 커뮤니케이션

  • 윈도우에서 해당 윈도우를 제어하는 서비스 워커로 메시지 보내기
  • 서비스 워커에서 범위 내의 모든 윈도우로 메시지 보내기
  • 서비스 워커에서 특정 윈도우로 메시지 보내기
  • 윈도우간 메시지 보내기 (서비스 워커를 통해)

페이지에서 서비스워커를 가져오려면 다음과 같이한다.

navigator.serviceWorker.controller

그 후에는 메시지 자체를 첫번째 인수로 받는 서비스 워커의 postMessage() 메서드를 활용한다.이 메시지는 무엇이든 될 수 있다.

메시지가 게시되고 나면 서비스 워커는 message 이벤트를 수신하여 해당 메시지를 받을 수 있다.

self.addEventListener("message", function (event) {
console.log(event.data)
})

위 예제는 메시지를 받아서 콘솔에 출력한다. 메시지에 포함된 콘텐츠는 이벤트 리스너에 전달된 이벤트 객체의 데이터 속성에서 찾을 수 있다. 메시지 데이터 자체를 포함하는 것 이외에도 이벤트 객체는 여러 유용한 속성을 가지고 있다. 가장 유용한 속성중 일부는 source 속성에 있다.

source 속성에는 메시지를 보낸 윈도우 정보가 들어있다. 이 정보를 활용해서 무엇을 할지 그리고 응답을 어디로 보낼지 판단할 수 있다. 다음 코드는 메시지의 source 속성을 사용하는 간단한 예제 코드이다.

self.addEventListener("message", function (event) {
console.log("Message received:", event.data)
console.log("From a window with the id:", event.source.id)
console.log("which is currently pointing at:", event.source.url)
console.log("and is", event.source.focused ? "focused" : "not focused")
console.log("and", event.source.visibilityState)
})

페이지에서 서비스워커로 해당 페이지를 캐시하라고 요청을 보낸다.

navigator.serviceWorker.controller.postMessage("cache-current-page")

사용자가 해당 페이지에 방문하면 서비스 워커에 메시지를 보냅니다. 서비스 워커는 이 메시지를 수신하고, 어느 페이지를 캐싱할지 결정하기 위해 이벤트 source 속성의 값을 사용할 수 있다.

서비스 워커에서 페이지로 메시지를 보내는 것은 페이지에서 서비스 워커로 메시지를 게시하는 것과 비슷하다. 유일한 차이점은 postMessage()를 호출하는 객체이다. 지금까지 서비스 워커에서 postMessage()를 호출했다면 이번에는 서비스 워커 클라이언트에서 호출한다.

서비스 워커내에서 서비스 워커의 글로벌 객체인 clients 객체를 사용해 현재 서비스 워커 범주안에 열려 있는 모든 윈도우(Window Clients)를 가져올 수 있다. clients 객체는 matchAll 메서드를 가지고 있다. 이 메서드는 서비스워커 범주 내에 열려 있는 모든 윈도우를 가져오는데 사용된다. matchAll() 메서드는 0개 혹은 그 이상의 WindowClient 객체를 담는 배열로 리졸브되는 프로미스를 반환한다.

self.clients.matchAll().then(function(clients) {
clients.forEach(function(client) {
if (client.url.includes("/my-account")) {
client.postMessage("Hi client: " + client.id;
}
})
})

이 코드는 현재 서비스 워커가 제어하는 모든 클라이언트를 가져와 하나씩 돌며 페이지를 표시하고 있는 윈도우로 메시지를 보낸다. 이 메시지를 윈도우에서 받는 코드는 아래와 같다.

navigator.serviceWorker.addEventListener("message", function (event) {
console.log(event.data)
})

서비스 워커가 설치되고 필요한 모든 리소스 캐싱이 끝나면 앱 사용자에게 온라인이든 오프라인이든 상관없이 앱을 사용할 수 있다고 알려야한다.

self.addEventListener('install', function() {
event.waitUntil (
caches.open(CACHE_NAME).then(function(cache) {
return cache.addAll(CACHED_URLS)
}).then(function() {
return self.clients.matchAll({
includeUncontrolled: true
})
}).then(function (clients) {
clients.forEach(client) {
client.postMessage('caching-complete')
}
})
)
})

위 코드에서 clients.matchAll()를 호출할 때 옵션 객체를 전달하여 제어되지 않는 클라이언트도 결과에 포함되도록 요청한다.

사용자가 페이지에 처음 방문하면 서비스 워커가 설치되고 활성화된다. 하지만 페이지는 여전히 서비스 워커에의해 제어되지 않는다. 만일 self.clients.matchAll()에 제어되지 않는 윈도우를 포함하지 않도록 알려주지 않았다면 메시지는 목적지에 도달하지 못한다.

LifeCycle

서비스 워커의 라이프사이클은 복잡하다.
서비스 워커가 무엇을 하려는지, 그리고 어떤 그 라이프사이클이 어떤 이점이 있는지 모른다면, 서비스워커와 싸우고 있는 것처럼 느껴질 수 있다. 하지만 작동 방식을 알고 나면 웹과 네이티브 패턴의 장점을 혼합하여 사용자에게 원활하고 눈에 거슬리지 않는 업데이트를 제공할 수 있다.

서비스 워커 라이프 사이클의 목적은 다음과 같다.

  • Make offline-first possible.
  • 새 서비스 워커가 현재 서비스 워커를 방해하지 않고 스스로 준비할 수 있도록 허용한다.
  • 범위 내 페이지가 전체적으로 동일한 서비스 워커에 의해 제어되는지(또는 서비스워커가 없는지) 확인한다.
  • 한 번에 하나의 사이트 버전만 실행되도록 한다.

마지막은 매우 중요하다. 서비스 워커가 없으면 사용자는 사이트에 하나의 탭을 로드한 다음 나중에 다른 탭을 열 수 있다. 이렇게 되면 사이트의 두 가지 버전이 동시에 실행될 수 있다. 가끔은 괜찮을 수도 있지만, 스토리지를 다루는 경우 공유 스토리지 관리 방식에 대해 서로 다른 의견을 가진 두 개의 탭이 쉽게 생길 수 있다. 이로 인해 오류가 발생하거나 최악의 경우 데이터가 손실될 수 있다.

라이프 사이클의 기본에 대해서 알아보자.

  • install 이벤트는 서비스 워커가 처음 받는 이벤트이며 한 번만 발생된다.
  • installEvent.waitUntil()에 전달된 프로미스는 설치의 기간과 성공 또는 실패를 알린다.
  • 서비스 워커는 성공적으로 설치를 완료하고 active가 될 때까지 가져오기 및 푸시 같은 이벤트를 수신하지 않는다.
  • 기본적으로 페이지 요청 자체가 서비스 워커를 거치지 않는 한 페이지의 fetch는 서비스 워커를 거치지 않는다. 따라서 서비스 워커의 효과를 확인하려면 페이지를 새로고침 해줘야한다.
  • clients.claim()은 기본값을 재정의하고 제어되지 않은 페이지를 제어할 수 있다.

Install

서비스 워커가 받는 첫 번째 이벤트는 install입니다. 이 이벤트는 워커가 실행되는 즉시 트리거되며 서비스 워커당 한 번만 호출됩니다. 서비스 워커 스크립트를 변경하면 브라우저는 이를 다른 서비스 워커로 간주하고 다른 설치 이벤트를 받는다.

설치 이벤트는 클라이언트를 제어하기 전에 필요한 모든 것을 캐시할 수 있는 기회이다. event.waitUntil()에 전달한 프로미스는 설치가 완료된 시점과 성공 여부를 브라우저에게 알려준다. 프로미스가 거부되면 설치에 실패했다는 신호가 되고 브라우저는 서비스 워커를 버린다.

Activate

서비스 워커가 클라이언트를 제어하고 pushsync와 같은 기능적 이벤트를 처리할 준비가 되면 활성화 이벤트를 받게 된다. 하지만 그렇다고 해서 .register()를 호출한 페이지가 제어되는 것은 아니다.

clients claim

서비스 워커가 활성화되면 서비스 워커 내에서 clients.claim()을 호출하여 제어되지 않는 클라이언트를 제어할 수 있다. 서비스 워커를 사용하여 페이지를 네트워크를 통해 로드할 때와 다르게 로드하는 경우 clients.claim() 없이 로드되는 일부 클라이언트를 서비스 워커가 제어하게 되므로 문제가 될 수 있다.(타이밍의 문제)

많은 사람들이 clients.claim()을 상용구처럼 사용하는 것을 보지만, 저는 거의 사용하지 않습니다. 처음 로드할 때만 중요하며, 점진적인 개선으로 인해 페이지가 서비스 워커 없이도 원활하게 작동하는 경우가 대부분이다.

Updating the service worker

다음 중 하나라도 발생하면 업데이트가 트리거된다.

  • 범위 내의 페이지로 이동하는 경우
  • 푸시 및 동기화와 같은 기능적 이벤트는 지난 24시간 이내에 업데이트 확인이 없는 경우이다.
  • 서비스 워커 URL이 변경된 경우에만 .register()를 호출한다. 그러나 워커 URL을 변경하지 않아야 한다.
  • Chrome 68 이상을 포함한 대부분의 브라우저는 등록된 서비스 워커 스크립트의 업데이트를 확인할 때 캐싱 헤더를 무시하도록 기본 설정되어 있다.importScripts()를 통해 서비스 워커 내부에 로드된 리소스를 가져올 떄는 여전히 캐싱 헤더를 존중한다. 서비스 워커를 등록할 때 updateViaCache 옵션을 설정하여 이 기본 동작을 재정의할 수 있다.
  • 서비스 워커가 브라우저에 이미 있는 것과 바이트 단위로 다르면 업데이트된 것으로 간주된다.
  • 업데이트된 서비스 워커는 기존 워커와 함께 시작되며 자체 설치 이벤트를 받는다.
  • 새 워커에 확인되지 않은 상태 코드가 있거나, 구문 분석에 실패하거나, 실행 중에 오류가 발생하거나, 설치 중에 거부되는 경우 새 워커는 버려지지만 현재 워커는 활성 상태로 유지된다.
  • 설치에 성공하면 업데이트된 워커는 기존 워커가 클라이언트를 0개 제어할 때까지 기다린다.
  • self.skipWaiting()은 대기를 방지하여 서비스 워커가 설치가 완료되는 즉시 활성화되도록 한다.

Install

캐시 이름을 static-v1에서 static-v2로 변경했습니다. 즉, 기존 서비스 워커가 여전히 사용 중인 현재 캐시의 내용을 덮어쓰지 않고 새 캐시를 설정할 수 있다.

이 패턴은 네이티브 앱이 실행 파일과 함께 번들로 제공하는 에셋과 유사하게 버전별 캐시를 생성한다. 아바타처럼 버전에 특정되지 않은 캐시가 있을 수도 있다.

Waiting

성공적으로 설치되면 업데이트된 서비스 워커는 기존 서비스 워커가 더 이상 클라이언트를 제어하지 않을 때까지 활성화를 지연한다. 이 상태를 "대기 중"이라고 하며, 브라우저에서 한 번에 하나의 서비스 워커 버전만 실행되도록 하는 방법이다.

데모 탭이 하나만 열려 있더라도 페이지를 새로 고치는 것만으로는 새 버전이 적용될 수 없다. 이는 브라우저 탐색이 작동하는 방식 때문이다. 탐색할 때 응답 헤더가 수신될 때까지 현재 페이지가 사라지지 않으며, 응답에 Content-Disposition 헤더가 있는 경우에도 현재 페이지가 유지될 수 있다. 이러한 중첩으로 인해 현재 현재 서비스 워커는 새로 고침 중에 항상 클라이언트를 제어해야한다.

Activate

이전 서비스 워커가 사라지고 새 서비스 워커가 클라이언트를 제어할 수 있게 되면 이 기능이 실행된다. 이때는 데이터베이스 마이그레이션, 캐시 지우기 등 이전 작업자가 사용 중 일 때는 할 수 없었던 작업을 수행하기에 이상적인 시기이다.

참고