서비스 워커를 사용한 작업

이 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 파일에 코드를 추가했으므로 샘플 프로젝트의 실시간 버전을 방문하여 서비스 워커가 작동하는 모습을 관찰해 보겠습니다.

  • 사이트를 미리 보려면 앱 보기를 누른 다음 전체 화면 전체 화면을 누릅니다.
  • `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를 사용하여 서비스 워커의 동작을 관찰하는 프로세스에 익숙해졌습니다.

이제 캐싱 전략을 구현하고 웹 앱을 안정적이고 빠르게 로드하는 데 도움이 되는 모든 기능을 구현할 수 있습니다.