버그가 있는 서비스 워커 삭제

버그가 있는 서비스 워커가 배포되면 문제가 발생합니다 예를 들어 서비스 워커는 등록 시 파싱되어 성공적으로 설치를 완료할 수 있습니다. 그러나 fetch 이벤트의 버그가 있는 코드로 인해 이벤트가 요청에 응답하지 않아 빈 페이지가 표시될 수 있습니다. 또 다른 가능성은 페이지 마크업이 적극적으로 캐시되어 서비스 워커가 후속 방문에 관해 Cache 인스턴스에서 오래된 마크업 응답만 반환하는 것입니다.

서비스 워커가 역효과를 낼 수 있는 방법은 여러 가지가 있는데 프로덕션 웹사이트에서는 두려운 문제입니다. 그럼에도 불구하고 모든 것을 잃은 것은 아닙니다. 상황을 해결하고 다시 정상적으로 이용할 수 있는 방법이 있습니다.

노옵스(no-ops) 서비스 워커 배포

일반적으로 버그가 있는 서비스 워커를 처리할 때는 fetch 이벤트 핸들러 없이 즉시 설치 및 활성화되는 기본 no-op 서비스 워커를 배포하기만 하면 됩니다.

// sw.js

self.addEventListener('install', () => {
  // Skip over the "waiting" lifecycle state, to ensure that our
  // new service worker is activated immediately, even if there's
  // another tab open controlled by our older service worker code.
  self.skipWaiting();
});

self.addEventListener('activate', () => {
  // Optional: Get a list of all the current open windows/tabs under
  // our service worker's control, and force them to reload.
  // This can "unbreak" any open windows/tabs as soon as the new
  // service worker activates, rather than users having to manually reload.
  self.clients.matchAll({
    type: 'window'
  }).then(windowClients => {
    windowClients.forEach((windowClient) => {
      windowClient.navigate(windowClient.url);
    });
  });
});

이 서비스 워커는 install 이벤트에서 self.skipWaiting()를 호출하여 즉시 설치 및 활성화됩니다. 선택적으로 activate 이벤트에 추가 코드를 배포하여 서비스 워커가 제어하는 WindowClient로 다른 열려 있는 탭을 강제로 새로고침할 수 있습니다.

노옵스(no-ops) 서비스 워커에는 fetch 이벤트 핸들러가 포함되지 않는 것이 매우 중요합니다. 서비스 워커가 요청을 처리하지 않으면 해당 요청은 서비스 워커가 없는 것처럼 브라우저로 전달됩니다. 노옵스(no-ops) 서비스 워커가 배포되면 버그가 있는 서비스 워커를 수정하여 나중에 업데이트로 배포할 수 있습니다.

이 접근 방식이 효과가 있는 이유는 브라우저가 서비스 워커를 HTTP 캐시에 배치하지 못하도록 강력한 보호 장치를 갖추고, 그리고 업데이트에 대한 서비스 워커 콘텐츠의 바이트 단위 검사를 수행하기 때문입니다. 이러한 기본값을 사용하면 버그가 있는 서비스 워커를 위해 노옵스(no-ops) 교체를 배포하여 문제를 신속하게 해결할 수 있습니다.

추가 조치

노옵스(no-ops) 서비스 워커를 배포해도 버그가 있는 서비스 워커를 무력화할 수 있지만 필요한 경우 추가 조치를 취할 수 있습니다.

이전 서비스 워커의 URL을 모르는 경우에는 어떻게 해야 하나요?

때때로 이전에 설치된 서비스 워커의 URL을 알 수 없습니다. 버전이 지정되었기 때문일 수 있습니다 (예: 파일 이름에 해시가 있음). 이 경우 등록되었을 수 있는 각 이전 서비스 워커의 URL과 일치하는 노옵스(no-ops) 서비스 워커를 배포하기가 어려울 수 있습니다. 개발자가 배포된 모든 서비스 워커 버전의 모든 해시를 기억하지 못할 가능성이 높으므로 이는 권장사항에 위배됩니다.

다행히 유용한 HTTP 요청 헤더가 서비스 워커 스크립트 Service-Worker에 대한 요청과 함께 전송됩니다. 웹 서버에서 이 헤더를 확인하고 대신 노옵스(no-ops) 서비스 워커를 제공하라는 요청을 가로챕니다. 이 기능을 수행하는 방법은 사용된 웹 서버와 백엔드 스택에 따라 다르므로 방법은 관련 언어 문서를 참조하세요.

향후 서비스 워커 배포의 경우 버전이 지정되지 않은 애셋 이름 (예: sw.js)을 유지하세요. 이렇게 하면 나중에 작업이 훨씬 덜 복잡해집니다.

Clear-Site-Data 헤더 설정

값이 'storage'Clear-Site-Data 응답 헤더가 설정되면 일부 브라우저에서 출처의 모든 서비스 워커가 등록 취소됩니다. 그러나 이 접근 방식에는 몇 가지 유의해야 할 사항이 있습니다.

이 헤더에 대한 지원은 전체 기능이 아니므로 이 헤더만으로는 문제를 해결할 수 없습니다. 따라서 노옵스(no-ops) 서비스 워커를 배포하는 것 외에 추가로 취해야 할 조치로 Clear-Site-Data를 고려하는 것이 가장 좋습니다.

영구적인 손상이 아님

버그가 있는 서비스 워커로 인해(특히 잘 알려진 대규모 웹사이트의 경우) 사용자 경험이 방해를 받을 때 겁을 먹을 수 있습니다. 하지만 이러한 피해는 일시적이며 되돌릴 수 있습니다!

상황을 해결하기 위해 노옵스(no-ops) 서비스 워커를 배포해야 하는 경우 사후에 시간을 들여 정확히 무엇이 잘못되었는지 파악합니다. 앞으로는 서비스 워커가 예상된 요청만 처리하도록 하세요. 스테이징 단계에서 자주 테스트하고 확신이 있는 경우에만 업데이트를 배포합니다.