서비스 워커를 사용한 작업

이 Codelab에서는 웹 애플리케이션 내에서 서비스 워커를 등록하고 Chrome DevTools를 사용하여 서비스 워커 동작을 관찰하는 방법을 보여줍니다. 또한 서비스 워커를 다룰 때 유용할 수 있는 몇 가지 디버깅 기법을 다룹니다.

샘플 프로젝트 숙지

이 Codelab과 가장 관련성이 높은 샘플 프로젝트의 파일은 다음과 같습니다.

  • register-sw.js는 비어 있는 것으로 시작하지만 서비스 워커를 등록하는 데 사용되는 코드를 포함합니다. 프로젝트의 index.html 내부에 있는 <script> 태그를 통해 이미 로드되고 있습니다.
  • 마찬가지로 service-worker.js도 비어 있습니다. 이 프로젝트의 서비스 워커를 포함할 파일입니다.

서비스 워커 등록 코드에 추가

서비스 워커 (현재 service-worker.js 파일과 같이 비어 있는 파일 포함)는 먼저 등록되지 않으면 사용되지 않습니다. 다음 호출을 통해 이 작업을 수행할 수 있습니다.

navigator.serviceWorker.register(
  '/service-worker.js'
)

register-sw.js 파일 내에 있어야 합니다.

그러나 이 코드를 추가하기 전에 몇 가지 사항을 고려해야 합니다.

첫째, 일부 브라우저는 서비스 워커를 지원하지 않습니다. 자동으로 업데이트되지 않는 이전 버전의 브라우저에서 특히 그렇습니다. 따라서 navigator.serviceWorker가 지원되는지 확인한 후 navigator.serviceWorker.register()를 조건부로 호출하는 것이 좋습니다.

둘째, 서비스 워커를 등록하면 브라우저에서 service-worker.js 파일의 코드를 실행하므로 서비스 워커의 installactivate 이벤트 핸들러에 있는 코드에 따라 캐시를 채우기 위해 URL을 다운로드할 수 있습니다.

추가 코드를 실행하고 애셋을 다운로드하면 브라우저에서 현재 웹페이지를 표시하는 데 사용할 수 있는 귀중한 리소스를 사용할 수 있습니다. 이러한 간섭을 방지하려면 브라우저에서 현재 페이지의 렌더링을 완료할 때까지 서비스 워커 등록을 지연하는 것이 좋습니다. 이를 근사화하는 편리한 방법은 window.load 이벤트가 실행될 때까지 기다리는 것입니다.

이 두 점을 종합하여 이 범용 서비스 워커 등록 코드를 register-sw.js 파일에 추가합니다.

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js');
  });
}

일부 서비스 워커 로깅 코드 추가

service-worker.js 파일은 일반적으로 서비스 워커 구현을 위한 모든 로직이 이동하는 위치입니다. 서비스 워커 수명 주기 이벤트, Cache Storage API, 웹 앱의 네트워크 트래픽에 대한 지식을 조합하여 완벽하게 제작된 서비스 워커를 만들어 모든 웹 앱의 요청을 처리할 수 있습니다.

그건 나중에 배울 것입니다. 이 단계에서는 다양한 서비스 워커 이벤트를 관찰하고 Chrome DevTools 사용에 익숙해져 서비스 워커의 상태를 디버그하는 데 중점을 둡니다.

이를 위해 다음 코드를 service-worker.js에 추가합니다. 그러면 다양한 이벤트에 대한 응답으로 DevTools 콘솔에 메시지를 로깅합니다 (다른 경우에는 하지 않음).

self.addEventListener('install', (event) => {
  console.log('Inside the install handler:', event);
});

self.addEventListener('activate', (event) => {
  console.log('Inside the activate handler:', event);
});

self.addEventListener(fetch, (event) => {
  console.log('Inside the fetch handler:', event);
});

DevTools의 서비스 워커 패널 익히기

register-sw.jsservice-worker.js 파일에 코드를 추가했으므로 이제 샘플 프로젝트의 서비스 중인 버전으로 이동하여 작동 중인 서비스 워커를 관찰해 보겠습니다.

  • 사이트를 미리 보려면 View App을 누른 다음 Fullscreen 전체 화면을 누릅니다.
  • `Control+Shift+J` (Mac의 경우 `Command+Option+J`)를 눌러 DevTools를 엽니다.
  • 콘솔 탭을 클릭합니다.

서비스 워커가 설치되고 활성화되었음을 보여주는 다음과 같은 로그 메시지가 표시됩니다.

서비스 워커가 설치되고 활성화되었음을 보여줍니다.

그런 다음 Applications(애플리케이션) 탭으로 이동하여 Service Workers(서비스 워커) 패널을 선택합니다. 다음과 같이 표시되어야 합니다.

서비스 워커 세부정보를 서비스 워커 패널에 표시합니다.

이를 통해 웹 앱 solar-donkey.glitch.me에 대해 소스 URL이 service-worker.js인 서비스 워커가 현재 활성화되어 실행 중임을 알 수 있습니다. 또한 현재 서비스 워커가 제어하는 하나의 클라이언트 (열린 탭)가 있음을 알려줍니다.

이 패널의 링크(예: Unregister 또는 stop)를 사용하여 디버깅 목적으로 현재 등록된 서비스 워커를 변경할 수 있습니다.

서비스 워커 업데이트 흐름 트리거

서비스 워커로 개발할 때 이해해야 할 주요 개념 중 하나는 업데이트 흐름입니다.

사용자가 서비스 워커를 등록하는 웹 앱을 방문하면 로컬 브라우저에 설치된 service-worker.js의 현재 사본에 대한 코드가 생성됩니다. 하지만 웹 서버에 저장된 service-worker.js의 버전을 업데이트하면 어떻게 될까요?

반복 방문자가 서비스 워커 범위 내에 있는 URL로 돌아오면 브라우저는 자동으로 최신 service-worker.js를 요청하고 변경사항이 있는지 확인합니다. 서비스 워커 스크립트에 달라진 점이 있는 경우, 새 서비스 워커는 설치 및 활성화하고 최종적으로 제어할 수 있게 됩니다.

프로젝트의 코드 편집기로 돌아가서 코드를 무엇이든 변경하여 이 업데이트 흐름을 시뮬레이션할 수 있습니다. 한 가지 빠른 변화는

self.addEventListener('install', (event) => {
  console.log('Inside the install handler:', event);
});

다음 코드로 교체합니다.

self.addEventListener('install', (event) => {
  console.log('Inside the UPDATED install handler:', event);
});

변경한 후 샘플 앱의 실시간 버전으로 돌아가서 DevTools Application 탭이 열려 있는 상태로 페이지를 새로고침합니다. 다음과 같이 표시됩니다.

설치된 서비스 워커의 두 가지 버전을 보여줍니다.

이는 이 시점에 두 가지 버전의 서비스 워커가 설치되어 있음을 보여줍니다. 이미 활성화된 이전 버전이 실행 중이며 현재 페이지를 제어합니다. 업데이트된 서비스 워커 버전은 바로 아래에 나열되어 있습니다. waiting 상태이며 이전 서비스 워커가 제어하는 열린 탭이 모두 닫힐 때까지 대기합니다.

이 기본 동작을 사용하면 웹 앱의 이전 버전과 호환되지 않는 리소스로 응답하는 fetch 핸들러와 같이 새 서비스 워커의 동작에 근본적인 차이가 있는 경우 사용자가 웹 앱의 이전 인스턴스를 모두 종료할 때까지 변경사항이 적용되지 않습니다.

요약

이제 Chrome의 DevTools를 사용하여 서비스 워커를 등록하고 서비스 워커의 동작을 관찰하는 과정에 익숙해지셨을 것입니다.

이제 캐싱 전략을 구현할 수 있으며, 웹 앱을 안정적이고도 안정적으로 빠르게 로드하는 데 도움이 되는 모든 요소를 살펴볼 수 있습니다.