새소식

300x250
2. 웹개발/개발 주저리

Unregistering Service Worker(서비스 워커 제거 하기)

  • -
728x90

안녕하세요. 갓대희 입니다. 이번 포스팅은 [  서비스 워커 제거 하는 방법   입니다. : )

 

0. 들어가기 앞서

 - 최근들어 "Service Worker"는 웹개발에 점점 더 자주 사용되며, CRA와 같은 많은 사용자들이 사용하는 라이브러리에 추가되기도 한다.
 - 다만, 여러가지 상황에 의해 Service Worker를 제거해야하는 상황이 발생 하기도 하는데.
이때 Service Worker가 의도대로 제거되지 않아, 고생하였다. 나와 같은 고충을 겪은 사람들이 간혹 있지 않을까 하여 Service Worker 제거 방법에 대해 고민했던 내용을 기록 해 보려 한다.

 - stack overflow의 도움을 많이 받았으며, 당연히 나와 같은 고민을 한 사람들을 많이 발견할 수 있었다.

 

 

※ 참고 1

 - CRA에서는 제공하는 PWA 관련 가이드, Service Worker를 적용하는 내용은 다음과 같다.

( 나는 특정 이유로 이미 해당 설정을 통해 적용된 고객들의 브라우저에서 "서비스 워커"를 해제 하고 싶다. )
https://create-react-app.dev/docs/making-a-progressive-web-app/

 

ex) 나의 경우 이제는 웹서버, CDN 등에 없는 버전의 React 빌드 파일들을 서비스 워커거 아직도 캐싱한 파일을 보유하고 있는 것을 캐칭할 수 있었다. 이러한 케이스가 모니터링 되었기 때문에 서비스 워커를 강제로 unregister 하려고 한다.

 

※ 참고2 

 - 전제 조건

서비스 워커를  브라우저에서 직접 제거할 수 있지만, 나의 경우는 실제 고객들의 앱, 웹뷰, 인앱 브라우저 등에서 제거하고 싶기 때문에 프로그래밍 방식, 소스를 통해 서비스 워커 제거하는 방법이 필요하다.

 

1. Service Worker Unregister 방법

방법1)  
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready.then(registration => {
      registration.unregister();
    });
}

https://stackoverflow.com/questions/49263942/service-worker-unregistered-but-still-running

 - 우리사이트의 경우 위와 같은 가이드를 통해 해제를 하고 있었고, 정말 일부, 특정 고객들은 서비스 워커가 해제 되지 않는 현상을 겪고 있었다.

 - 물론 매우 일반적인 상태, 환경에서는 정상 동작 하였다.

ex) Service Worker가 설치 된 상태 ex) 위의 함수 실행 후 unregister된 상태
 

 

방법2)  
if ('serviceWorker' in navigator) {
	navigator.serviceWorker.getRegistrations().then(function (registrations) {
		for (const registration of registrations) {
			// unregister service worker
			console.log('serviceWorker unregistered');
			registration.unregister();
		}
	});
}

 

 - 이해를 위해 간단하게 작성한 예시이며, 조금더 자세한 내용은 하기 github을 참고해도 된다.

https://gist.github.com/mrienstra/9c60a76009480e2240770dadb2fb96fe

navigator.serviceWorker.getRegistrations().then(function (registrations) {
  if (!registrations.length) {
    console.log('No serviceWorker registrations found.')
    return
  }
  for(let registration of registrations) {
    registration.unregister().then(function (boolean) {
      console.log(
        (boolean ? 'Successfully unregistered' : 'Failed to unregister'), 'ServiceWorkerRegistration\n' +
        (registration.installing ? '  .installing.scriptURL = ' + registration.installing.scriptURL + '\n' : '') +
        (registration.waiting ? '  .waiting.scriptURL = ' + registration.waiting.scriptURL + '\n' : '') +
        (registration.active ? '  .active.scriptURL = ' + registration.active.scriptURL + '\n' : '') +
        '  .scope: ' + registration.scope + '\n'
      )
    })
  }
})

 

ex) Service Worker가 설치된 상태 ex) 위의 함수 실행 후 unregister된 상태

 

 

※ 다음과 같은 내용에 의해 공감하였고, 위의 2가지 방법을 다 고려 해보려 한다. 

 - getRegistrations, getRegistration 두 개의 API를 모두 사용 하라는 의미이다.

 

 - 특정 플랫폼, 브라우저마다 호환성이 다르기 때문이라는 것 같다. 

※ 우리 사이트의 경우 getRegistration을 통해서만 ServiceWorker를 제거하고 있었다. 혹시 몰라 error 모니터링 툴을 적용하여 에러가 발생여부를 체크 해 보았다.

 

 - 아니나 다를까 TypeError가 발생하고 있었다. 

 - 혹시나 몰라 현 시점의 호환성 또한 체크 해 보았다.

getRegistration getRegistrations

 

 - 약간 다른 부분이 있었고, 우리의 경우 Naver 앱의 웹뷰, 삼성 브라우저 등 대부분 웹뷰에서의 현상으로써 두가지 방안을 다 적용 해보는 것으로 고려 해야 겠다.

 


※ 상기 두가지 방안으로 해결 되지 않을경우 해볼 수 있는 추가 방법 들

방법3) clear cache of service worker
if ('caches' in window) {
    caches.keys()
      .then(function(keyList) {
          return Promise.all(keyList.map(function(key) {
              return caches.delete(key);
          }));
      })
}

 - 추가 작업으로 직접 캐시를 삭제 하는 방법을 제시하는 사람들도 있었다. 해당 작업만으로 서비스 워커가 unregister 되는 것은 아니다.

 

※ 이 얘기가 왜 나왔는지는 다음 예시로 설명 하려고 한다.

ex) 현재 시점 : 2023년11월 20일

 - 상기 방법1), 방법2) 만 수행하였을 경우

 

1) 서비스 워커는 제거 되었다.

 

2) 하지만 과거의 캐시 찌꺼기는 다음과 같이 약 반년이 지났음에도 남아있는 것을 볼 수 있다.

 

 - 이 찌꺼기를 지워 주자라는 얘기이다. 상기 스크립트 수행 후 다음과 같이 비워지는것을 볼 수 있다.

 

방법4)
(await navigator.serviceWorker.ready).unregister()

 - 브레이브라는 브라우저를 써본 분들이 있을 것 이다. ( 나도 가끔 사용 하곤 한다. 엄청난 브라우저 이다. )

 - 해당 brave를 사용하는 유저입장에서는 상기 방법이 다 통하지 않았다고 하여 사용한 방법이니 해당 방법도 고려 해볼 수 있다면, 고려해 보려고 한다. (네이버 웹뷰에서도 발생할 수 있지 않을까? )

 

ex) Service Worker가 설치된 상태 ex) 위의 함수 실행 후 unregister된 상태

 

방법5)
self.addEventListener('install', function(e) {
  self.skipWaiting();
});

self.addEventListener('activate', function(e) {
  self.registration.unregister()
    .then(function() {
      return self.clients.matchAll();
    })
    .then(function(clients) {
      clients.forEach(client => client.navigate(client.url))
    });
});

 - https://github.com/NekR/self-destroying-sw

 - 나와 같이 서비스워커 업데이트를 더이상 제공하지 않는 경우 다음과 같은 방법을 쓸 수 있다고 한다.

▶ 적용 방법1) ServiceWorker에 대한 모든 항목(등록/제거 코드, ServiceWorker 파일)을 제거 한다.2) 이전 ServiceWorker와 동일한 이름의 파일을 생성하여 이전 ServiceWorker가 있던 동일한 위치에 배치합니다.     즉, 동일한 파일명, 위치에 위의 소스코드를 적용 한다.3) 프로젝트를 배포하면 자동으로 제거 된다. 4) MIT 라이센스 ㅎㅎ - 혹시나 상기 github url이 없어질 수 있으니 이미지로 캡쳐 해 왔다. 

https://github.com/NekR/self-destroying-sw

 

 

※ 대 고객 서비스에서 한번 적용하긴 쉽지만,  완벽히 제거하기란 여간 쉽지 않은 작업인 것 같다.나와 같은 고통을 겪은 분들에게 조금이나마 도움이 되면 좋겠다.

 

※ 모든 내용은 하기 stack overflow를 참고 하였다.

https://stackoverflow.com/questions/33704791/how-do-i-uninstall-a-service-worker/33705250#33705250

 

※ 참고 - 크롬 개발자 도구를 통해서도 확인 하였다. 

chrome://serviceworker-internals/

( 급한 마음에 cafe24 사이트를 잠깐 활용하였고, 감사합니다. 문제가 된다면 다른 예시를 사용하도록 하겠습니다 :-0)

 

300x250
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.