서비스 워커를 사용한 작업

이 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를 사용하여 서비스 워커를 등록하고 서비스 워커의 동작을 관찰하는 프로세스에 익숙해졌을 것입니다.

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