Service Worker는 페이지와 별도 실행 맥락에서 네트워크 요청이나 캐시 작업을 처리하지만, 등록 즉시 모든 페이지를 제어하지는 않습니다. 브라우저는 설치, 대기, 활성화 같은 수명주기를 관리하고, 기존 worker가 제어 중인 페이지가 남아 있으면 새 worker의 활성화를 늦출 수 있습니다. 이 순서를 이해하면 업데이트가 배포됐는데도 일부 탭에서 이전 동작이 계속되는 상황을 설명할 수 있습니다.

두 페이지 버전 사이의 Service Worker 전환 개념도

개념 그림이며 실제 브라우저 화면이나 측정 시간을 나타내지 않습니다.

1. 등록에서 설치와 활성화까지

페이지는 HTTPS 등 보안 컨텍스트에서 Service Worker를 등록하고, 브라우저는 스크립트를 가져와 설치를 시도합니다. install 단계에서 필요한 초기 캐시를 채우거나 설치 실패를 처리할 수 있습니다. 설치가 성공해도 새 worker가 곧바로 기존 worker를 대체하는 것은 아닙니다. 일반적으로 현재 해당 registration 아래에서 열린 클라이언트를 이전 worker가 제어하고 있으면 새 worker는 waiting 상태에 머무릅니다.

기존 클라이언트의 제어가 끝나면 수명주기와 미완료 이벤트 조건에 따라 활성화가 가능해집니다. activate에서 앱이 소유한 CacheStorage를 정리할 수 있지만 완료는 보장되지 않습니다. 이는 HTTP 캐시와 별개입니다. lifecycle event는 순서가 정해진 브라우저 관리 절차이며, 사이트 코드가 언제든 임의로 단계를 건너뛸 수 있는 일반적인 작업 큐가 아닙니다.

2. waiting이 업데이트의 안정성을 돕는 이유

대기는 페이지의 수명 동안 서로 다른 worker 버전에서 자원을 가져오는 혼합 상태를 줄이는 데 도움이 됩니다. 예를 들어 새 worker가 캐시 형식이나 메시지 프로토콜을 바꾸면 기존 페이지와 새 worker의 조합이 예상하지 못한 결과를 만들 수 있습니다. 기존 탭이 끝나기 전에 새 버전이 제어를 가져오지 않도록 기다리면 점진적 업데이트에 안정성을 줄 수 있습니다.

그 결과 이용자는 업데이트 직후에도 열린 탭에서 예전 파일이나 동작을 볼 수 있습니다. 이것이 항상 업데이트 실패를 뜻하는 것은 아닙니다. 웹앱은 대기 중인 버전을 감지해 사용자와 전환 시점을 정할 수 있습니다. 탐색 중 클라이언트가 겹칠 수 있어 새로고침만으로 활성화가 보장되지는 않습니다. 중요한 데이터 입력 중인 페이지를 강제로 다시 불러오지 않도록 사용자 흐름을 고려합니다.

3. skipWaiting과 clients.claim의 범위

skipWaiting()은 활성화를 요청하며 설치를 생략하거나 동기적으로 전환을 끝내지 않습니다. 활성화는 이미 제어 중인 클라이언트를 새 worker로 넘깁니다. 활성화 중인 경우도 포함한 active worker는 clients.claim()으로 registration과 scope에 맞는 적격 클라이언트를 제어할 수 있습니다. 교체 인계에 claim이 필수인 것은 아닙니다. 이 선택은 업데이트를 빠르게 적용할 수 있지만 기존 페이지 코드가 기대하는 자원이나 프로토콜과 새 worker의 동작이 달라질 위험을 키웁니다. 두 API는 자동적인 안전성 기능이 아닙니다.

즉시 전환을 택한다면 캐시 버전, 요청 형식, 메시지 호환성을 고려하고 구버전 페이지가 새 worker와 함께 작동하는지 시험합니다. 특히 HTML과 정적 자산이 서로 다른 배포 버전에서 제공될 때 중간 상태를 다뤄야 합니다. 빠른 전환이 필요한 이유가 명확하지 않다면 기본 대기 동작을 유지하고 이용자가 안전하게 새로고침할 시점을 선택하게 하는 편이 낫습니다.

4. 전문가 관점: 업데이트를 관측 가능하게 만들기

Service Worker 표준은 registration, install·waiting·activate 흐름과 클라이언트 제어 규칙을 정의합니다. MDN 안내는 scope와 브라우저 관리를 요약합니다. Jake Archibald의 당시 생명주기 설명은 첫 페이지 제어와 버전 혼합 위험을 강조합니다. 각 페이지의 제어 상태는 registration과 controller 관계에 따라 달라지므로, 새 worker 파일이 배포됐다는 사실만으로 열린 모든 탭이 즉시 새 코드로 바뀌었다고 결론 내릴 수 없습니다.

운영에서는 업데이트 설치 여부, waiting 여부, 활성 controller 버전을 사용자에게 방해되지 않는 방식으로 표시할 수 있습니다. 테스트에는 첫 방문, 기존 탭을 연 채 업데이트, 여러 탭, 오프라인 전환, 설치 실패와 재시도를 포함합니다. skipWaiting이나 clients.claim은 필요성과 호환성 근거가 있을 때만 적용하고, 데이터 변경 중 강제 전환을 피합니다. lifecycle 상태를 관측하면 지원 문의와 캐시 문제를 추적하기 쉬워집니다.

출처