서비스 워커를 Google 검색에 도입

출시 내용, 영향 측정 방법, 그리고 그에 따른 장단점을 설명합니다.

배경

Google에서 거의 모든 주제를 검색하면 의미 있고 관련성 높은 결과를 즉시 알아볼 수 있는 페이지가 표시됩니다. 모르셨을 점은 특정 시나리오에서 서비스 워커라고 하는 강력한 웹 기술이 이 검색결과 페이지에 게재된다는 점입니다.

성능에 부정적인 영향을 미치지 않으면서 Google 검색에 서비스 워커 지원을 출시하려면 여러 팀에서 일하는 수십 명의 엔지니어가 필요했습니다. 즉, 무엇이 발송되었는지, 성능을 어떻게 측정했는지, 어떤 장단점이 있는지를 알 수 있습니다.

서비스 워커를 탐색해야 하는 주요 이유

사이트의 아키텍처를 변경하는 것과 마찬가지로 웹 앱에 서비스 워커를 추가할 때도 명확한 목표를 염두에 두고 수행해야 합니다. Google 검색팀에서 서비스 워커를 추가할 가치가 있는 몇 가지 주요 이유가 있었습니다.

제한된 검색 결과 캐싱

Google 검색팀은 사용자가 짧은 시간 내에 동일한 용어를 두 번 이상 검색하는 것이 일반적이라는 사실을 발견했습니다. Google 검색팀은 단순히 동일한 결과를 얻기 위해 새 백엔드 요청을 트리거하는 대신 캐싱을 활용하여 이러한 반복 요청을 로컬에서 처리하고자 했습니다.

최신성의 중요성은 결코 무시할 수 없습니다. 간혹 같은 검색어를 반복적으로 검색하는 사용자는 계속해서 변화하는 주제이기 때문에 참신한 결과를 기대할 수 있기 때문입니다. Google 검색팀은 서비스 워커를 사용하여 세분화된 로직을 구현하여 로컬로 캐시된 검색결과의 전체 기간을 제어하고 사용자에게 가장 적합하다고 생각되는 속도와 최신 상태 간의 정확한 균형을 유지할 수 있습니다.

의미 있는 오프라인 경험

또한 Google 검색팀은 의미 있는 오프라인 경험을 제공하고자 했습니다. 사용자는 특정 주제에 관해 알고자 할 때 인터넷 연결 상태에 신경 쓰지 않고 Google 검색 페이지로 바로 이동해 검색을 시작하려고 합니다.

서비스 워커가 없는 상태에서 오프라인 상태에서 Google 검색 페이지를 방문하면 브라우저의 표준 네트워크 오류 페이지로 연결되며 사용자는 연결이 반환되면 돌아와서 다시 시도해야 합니다. 서비스 워커를 사용하면 커스텀 오프라인 HTML 응답을 제공하고 사용자가 즉시 검색어를 입력하도록 할 수 있습니다.

백그라운드 재시도 인터페이스의 스크린샷

인터넷에 연결될 때까지 결과가 제공되지 않지만 서비스 워커는 기기가 백그라운드 동기화 API를 사용하여 다시 온라인 상태가 되는 즉시 검색을 연기하고 Google 서버로 전송할 수 있도록 허용합니다.

더 스마트한 자바스크립트 캐싱 및 제공

또 다른 동기는 검색결과 페이지의 다양한 유형의 기능을 구동하는 모듈화된 JavaScript 코드의 캐싱과 로드를 최적화하는 것이었습니다. 자바스크립트 번들 기능을 사용하면 서비스 워커의 개입이 없을 때 의미가 있는 여러 이점이 있으므로 Google 검색팀은 단순히 번들링을 완전히 중단하고 싶지 않았습니다.

Google 검색팀은 런타임에 JavaScript의 세분화된 청크를 버전 및 캐시하는 서비스 워커의 기능을 이용하여 캐시 이탈을 줄이고 향후 재사용되는 JavaScript를 효율적으로 캐시할 수 있을 것이라고 생각했습니다. 서비스 워커 내부의 로직은 여러 JavaScript 모듈이 포함된 번들의 발신 HTTP 요청을 분석하고 로컬에서 캐시된 여러 모듈을 연결하여 처리할 수 있습니다. 가능한 경우 효과적으로 '번들 해제'합니다. 이렇게 하면 사용자 대역폭이 절약되고 전반적인 응답성이 향상됩니다.

또한 서비스 워커가 제공하는 캐시된 자바스크립트를 사용하면 성능상의 이점이 있습니다. Chrome에서는 자바스크립트의 파싱된 바이트 코드 표현이 저장 및 재사용되므로 페이지에서 자바스크립트를 실행하기 위해 런타임에 실행해야 하는 작업이 줄어듭니다.

도전과제 및 솔루션

다음은 팀이 명시한 목표를 달성하기 위해 극복해야 할 몇 가지 장애물입니다. 이러한 문제 중 일부는 Google 검색에 국한되지만 서비스 워커 배포를 고려할 수 있는 다양한 사이트에 적용할 수 있습니다.

문제: 서비스 워커 오버헤드

가장 큰 문제이자 Google 검색에서 서비스 워커를 실행하는 데 있어 가장 큰 장애물은 서비스 워커가 사용자 인식 지연 시간을 늘릴 수 있는 작업을 하지 않도록 하는 것이었습니다. Google 검색은 성능을 매우 중요하게 생각하며, 이전에는 특정 사용자에게 수십 밀리초의 추가 지연 시간이 발생하는 경우 새로운 기능의 실행을 차단했습니다.

팀이 초기 실험에서 성능 데이터를 수집하기 시작했을 때 문제가 있음이 분명해졌습니다. 검색결과 페이지의 탐색 요청에 대한 응답으로 반환되는 HTML은 동적이며 Google 검색의 웹 서버에서 실행해야 하는 로직에 따라 크게 달라집니다. 현재 서비스 워커가 이 로직을 복제하고 캐시된 HTML을 즉시 반환할 수 있는 방법은 없습니다. 최선의 방법은 네트워크 요청이 필요한 백엔드 웹 서버에 탐색 요청을 전달하는 것입니다.

서비스 워커가 없으면 사용자가 탐색하는 즉시 이 네트워크 요청이 발생합니다. 서비스 워커가 등록되면 항상 시작되어야 하며, 가져오기 핸들러가 네트워크로 이동하는 것 외에 다른 작업을 할 가능성이 없는 경우에도 fetch 이벤트 핸들러를 실행할 기회를 제공해야 합니다. 서비스 워커 코드를 시작하고 실행하는 데 걸리는 시간은 모든 탐색에 추가되는 순수한 오버헤드입니다.

탐색 요청을 차단하는 SW 시작을 보여주는 그림입니다.

이로 인해 서비스 워커 구현은 다른 이점을 정당화하기에는 지연 시간 측면에서 지나치게 불리합니다. 또한 팀은 실제 기기에서 서비스 워커 부팅 시간을 측정했을 때 시작 시간이 광범위하게 분포되어 있음을 발견했습니다. 일부 저사양 휴대기기는 결과 페이지의 HTML에 대한 네트워크 요청을 하는 데 걸리는 시간만큼 서비스 워커를 시작하는 데 거의 시간이 걸렸습니다.

해결 방법: 탐색 미리 로드 사용

Google 검색팀이 서비스 워커 출시를 앞당길 수 있었던 가장 중요한 단일 기능은 탐색 미리 로드입니다. 탐색 미리 로드를 사용하면 탐색 요청을 충족하기 위해 네트워크의 응답을 사용해야 하는 모든 서비스 워커의 주요 성능상 이점을 얻을 수 있습니다. 서비스 워커가 시작되는 동시에 탐색 요청을 즉시 시작하라는 힌트를 브라우저에 제공합니다.

탐색 요청과 동시에 실행된 SW 시작을 보여주는 그림입니다.

서비스 워커가 시작되는 데 걸리는 시간이 네트워크에서 응답을 다시 받는 데 걸리는 시간보다 짧다면 서비스 워커에 의해 발생하는 지연 시간 오버헤드가 발생하지 않습니다.

또한 Google 검색팀은 서비스 워커의 부팅 시간이 탐색 요청을 초과할 수 있는 저사양 휴대기기에서 서비스 워커를 사용하지 않아야 했습니다. '저사양' 기기를 구성하는 항목에 관한 엄격하고 빠른 규칙이 없으므로 기기에 설치된 총 RAM을 확인하는 휴리스틱을 생각해 냈습니다. 2GB 미만의 메모리는 서비스 워커 시작 시간이 허용되지 않는 저사양 기기 카테고리에 속합니다.

나중에 사용하기 위해 캐시할 전체 리소스 집합이 수 MB까지 실행될 수 있으므로 사용 가능한 저장공간도 또 다른 고려사항입니다. navigator.storage 인터페이스를 사용하면 Google 검색 페이지에서 데이터 캐시 시도가 저장용량 할당량 실패로 인해 실패할 위험이 있는지 미리 파악할 수 있습니다.

이로 인해 Google 검색팀은 서비스 워커를 사용할지 여부를 결정하는 데 사용할 수 있는 여러 기준을 갖게 되었습니다. 사용자가 탐색 미리 로드를 지원하는 브라우저를 사용하여 Google 검색 페이지를 방문하고 최소 2GB의 RAM과 충분한 여유 저장공간이 있는 경우 서비스 워커가 등록됩니다. 이 기준을 충족하지 않는 브라우저나 기기에는 서비스 워커가 제공되지 않지만 이전과 동일한 Google 검색 환경이 계속 표시됩니다.

이러한 선택적 등록의 한 가지 이점은 더 작고 효율적인 서비스 워커를 제공할 수 있다는 점입니다. 최신 브라우저를 타겟팅하여 서비스 워커 코드를 실행하면 이전 브라우저의 변환 컴파일 및 폴리필 오버헤드가 사라집니다. 그 결과 서비스 워커의 전체 크기에서 약 8KB의 압축되지 않은 JavaScript 코드가 잘렸습니다.

문제: 서비스 워커 범위

Google 검색팀에서 충분한 지연 시간 실험을 실행하고 탐색 미리 로드가 서비스 워커를 사용하기 위한 실행 가능하고 지연 시간 중립적인 경로를 제공한다고 확신하자 몇 가지 실용적인 문제가 전면에 나타나기 시작했습니다. 이러한 문제 중 하나는 서비스 워커의 범위 지정 규칙과 관련이 있습니다. 서비스 워커의 범위에 따라 잠재적으로 제어할 수 있는 페이지가 결정됩니다.

범위 지정은 URL 경로 접두사를 기반으로 합니다. 단일 웹 앱을 호스팅하는 도메인의 경우 문제가 되지 않습니다. 일반적으로 도메인 아래의 모든 페이지를 제어할 수 있는 최대 범위가 /인 서비스 워커를 사용하기 때문입니다. 하지만 Google 검색의 URL 구조는 조금 더 복잡합니다.

서비스 워커에 /의 최대 범위가 주어지면 www.google.com (또는 그에 상응하는 리전)에서 호스팅되는 모든 페이지를 제어할 수 있으며, 해당 도메인 아래에는 Google 검색과 아무런 관련이 없는 URL이 있습니다. 더 합리적이고 제한적인 범위는 /search입니다. 이 범위에서는 최소한 검색결과와 관련이 없는 URL을 제거합니다.

안타깝게도 /search URL 경로가 다양한 유형의 Google 검색 결과 간에 공유되더라도, 표시되는 특정 유형의 검색결과를 결정하는 URL 쿼리 매개변수를 사용합니다. 이러한 버전 중 일부는 기존의 웹 검색 결과 페이지와 완전히 다른 코드베이스를 사용합니다. 예를 들어 이미지 검색과 쇼핑 검색은 모두 서로 다른 쿼리 매개변수로 /search URL 경로에 게재되지만 두 인터페이스 모두 아직 자체 서비스 워커 환경을 제공할 준비가 되어 있지 않았습니다.

솔루션: 디스패치 및 라우팅 프레임워크 만들기

URL 경로 프리픽스보다 더 강력한 방법으로 서비스 워커 범위를 결정할 수 있는 제안도 있지만, Google 검색팀은 제어된 일부 페이지에 아무런 작업도 하지 않는 서비스 워커를 배포하는 데 어려움을 겪었습니다.

이 문제를 해결하기 위해 Google 검색팀은 클라이언트 페이지의 쿼리 매개변수와 같은 기준을 확인하고 이를 사용하여 실행할 특정 코드 경로를 결정하도록 구성할 수 있는 맞춤형 디스패치 및 라우팅 프레임워크를 구축했습니다. 하드코딩 규칙 대신 이 시스템은 유연성이 좋으며 이미지 검색 및 쇼핑 검색과 같이 URL 공간을 공유하는 팀이 자체 서비스 워커 로직을 구현하기로 결정한 경우 입력할 수 있도록 설계되었습니다.

문제: 맞춤 검색결과 및 측정항목

사용자는 Google 계정을 사용하여 Google 검색에 로그인할 수 있으며 검색 결과 환경은 특정 계정 데이터를 기반으로 맞춤설정될 수 있습니다. 로그인한 사용자는 오래되고 널리 지원되는 표준인 특정 브라우저 쿠키로 식별됩니다.

하지만 브라우저 쿠키 사용의 한 가지 단점은 쿠키가 서비스 워커 내부에 노출되지 않고 사용자가 로그아웃하거나 계정 전환으로 인해 값이 변경되지 않도록 자동으로 값을 검사할 수 없다는 것입니다. 서비스 워커에 쿠키 액세스를 제공하기 위한 노력이 진행 중이지만 이 문서의 작성 시점을 기준으로 이 방법은 실험용이며 널리 지원되지는 않습니다.

현재 로그인한 사용자에 대한 서비스 워커의 뷰와 Google 검색 웹 인터페이스에 로그인한 실제 사용자가 일치하지 않으면 잘못된 맞춤 검색결과 또는 기여 분석 측정항목과 로깅이 잘못 표시될 수 있습니다. 이러한 장애 시나리오는 Google 검색팀에 심각한 문제가 될 수 있습니다.

해결 방법: postMessage를 사용하여 쿠키 전송

Google 검색팀은 실험용 API가 실행되고 서비스 워커 내부의 브라우저 쿠키에 직접 액세스할 때까지 기다리는 대신 임시방편 솔루션을 사용했습니다. 즉, 서비스 워커가 제어하는 페이지가 로드될 때마다 페이지에서 관련 쿠키를 읽고 postMessage()를 사용하여 쿠키를 서비스 워커로 보냅니다.

그런 다음 서비스 워커가 현재 쿠키 값을 예상한 값과 비교하여 확인합니다. 일치하지 않는 경우 저장소에서 사용자별 데이터를 삭제하는 단계를 따른 후 잘못된 맞춤설정 없이 검색 결과 페이지를 새로고침합니다.

서비스 워커가 사물을 기준으로 재설정하기 위해 실행하는 특정 단계는 Google 검색의 요구사항에 따라 다르지만, 브라우저 쿠키에서 키로 생성한 개인 맞춤 데이터를 처리하는 다른 개발자에게도 동일한 일반적인 접근 방식이 유용할 수 있습니다.

문제: 실험과 역동적

앞서 언급했듯이 Google 검색팀은 프로덕션 환경에서 실험을 실행하고, 새로운 코드와 기능을 기본적으로 사용 설정하기 전에 실제로 미치는 영향을 테스트하는 데 크게 의존합니다. 캐시된 데이터에 크게 의존하는 정적 서비스 워커의 경우, 사용자를 실험에 참여시키고 참여를 중지하는 데 백엔드 서버와 통신해야 하는 경우가 많으므로 이는 다소 문제가 될 수 있습니다.

솔루션: 동적으로 생성된 서비스 워커 스크립트

팀에서 선택한 솔루션은 미리 생성되는 단일 정적 서비스 워커 스크립트 대신 동적으로 생성된 서비스 워커 스크립트를 개별 사용자별로 웹 서버에서 맞춤설정하는 것이었습니다. 일반적으로 서비스 워커의 동작이나 네트워크 요청에 영향을 줄 수 있는 실험에 대한 정보는 이 맞춤설정된 서비스 워커 스크립트에 직접 포함됩니다. 사용자의 활성 환경 세트를 변경할 때는 브라우저 쿠키와 같은 기존 기술을 조합하고 등록된 서비스 워커 URL에 업데이트된 코드를 제공하여 변경할 수 있습니다.

또한 동적으로 생성된 서비스 워커 스크립트를 사용하면 서비스 워커 구현에 피해야 할 치명적인 버그가 있을 때 이스케이프 해치를 더 쉽게 제공할 수 있습니다. 동적 서버 워커 응답은 노옵스(no-ops) 구현일 수 있으며, 현재 사용자 일부 또는 전체에 대해 서비스 워커를 효과적으로 사용 중지합니다.

문제: 업데이트 조정

실제 서비스 워커 배포 시 직면하는 가장 어려운 과제 중 하나는 캐시에 유리한 네트워크를 피하는 동시에 기존 사용자가 프로덕션에 배포된 직후에 중요 업데이트와 변경사항을 받을 수 있도록 하는 것 사이에서 합리적인 절충점을 고안하는 것입니다. 적절한 균형은 다양한 요인에 따라 달라집니다

  • 웹 앱이 사용자가 새 페이지로 이동하지 않고 무기한 열어 두는 장기 단일 페이지 앱인지 여부
  • 백엔드 웹 서버 업데이트의 배포 주기입니다.
  • 일반 사용자가 약간 오래된 버전의 웹 앱 사용을 용인할 수 있는지 또는 최신 상태가 최우선순위인지 여부

Google 검색팀은 서비스 워커를 실험하면서 측정항목 및 사용자 환경이 재방문 사용자에게 표시되는 것과 더 밀접하게 일치되도록 예약된 여러 백엔드 업데이트를 통해 실험을 계속 실행했습니다.

솔루션: 최신성과 캐시 사용률의 균형 유지

Google 검색팀은 여러 가지 구성 옵션을 테스트한 후 다음 설정이 최신성과 캐시 사용률 간에 적절한 균형을 이루는 것으로 나타났습니다.

서비스 워커 스크립트 URL은 Cache-Control: private, max-age=1500 (1, 500초 또는 25분) 응답 헤더와 함께 제공되며, 헤더가 적용되도록 updateViaCache를 'all'로 설정하여 등록됩니다. Google 검색 웹 백엔드는 가능한 한 100% 에 가까운 업타임이 요구되는 전 세계에 분산된 대규모 서버 집합입니다. 서비스 워커 스크립트의 콘텐츠에 영향을 미치는 변경사항 배포는 롤링 방식으로 수행됩니다.

사용자가 업데이트된 백엔드를 방문한 후 아직 업데이트된 서비스 워커를 받지 않은 백엔드에 도달하는 다른 페이지로 빠르게 이동하면 버전 간에 여러 번 뒤집히게 됩니다. 따라서 마지막 검사에서 25분이 지난 후에야 업데이트된 스크립트를 확인하도록 브라우저에 지시하면 큰 단점이 없습니다. 이 동작을 선택하면 서비스 워커 스크립트를 동적으로 생성하는 엔드포인트에서 수신하는 트래픽이 크게 줄어듭니다.

또한 ETag 헤더가 서비스 워커 스크립트의 HTTP 응답에 설정되므로 25분이 지난 후 업데이트 확인을 수행할 때 서버는 중간에 배포된 서비스 워커에 업데이트가 없는 경우 HTTP 304 응답을 사용하여 효율적으로 응답할 수 있습니다.

Google 검색 웹 앱 내의 일부 상호작용은 History API를 통해 단일 페이지 앱 스타일 탐색을 사용하지만 대부분의 경우 Google 검색은 '실제' 탐색을 사용하는 기존 웹 앱입니다. 이는 팀이 서비스 워커 업데이트 수명 주기를 가속화하는 두 가지 옵션인 clients.claim()skipWaiting()를 사용하는 것이 효과적이라고 판단했을 때 적용됩니다. Google 검색의 인터페이스를 클릭하면 일반적으로 새 HTML 문서로 이동합니다. skipWaiting를 호출하면 업데이트된 서비스 워커가 설치 직후 새 탐색 요청을 처리할 수 있습니다. 마찬가지로 clients.claim()를 호출하면 업데이트된 서비스 워커가 서비스 워커 활성화 후 제어되지 않는 모든 열린 Google 검색 페이지를 제어할 수 있게 됩니다.

Google 검색이 채택한 접근 방식이 반드시 모든 사용자에게 적합한 솔루션이 아닐 수 있습니다. 이러한 접근 방식은 가장 효과적인 옵션을 찾을 때까지 다양한 게재 옵션 조합에 대해 신중하게 A/B 테스트를 진행한 결과입니다. 백엔드 인프라를 통해 업데이트를 더 빠르게 배포할 수 있는 개발자는 브라우저가 항상 HTTP 캐시를 무시하여 업데이트된 서비스 워커 스크립트를 최대한 자주 확인하는 것을 선호할 수 있습니다. 사용자가 장시간 열어 둘 수 있는 단일 페이지 앱을 빌드하는 경우에는 skipWaiting()를 사용하는 것이 적합하지 않을 수 있습니다. 수명이 긴 클라이언트가 있는 동안 새 서비스 워커가 활성화되도록 허용하면 캐시 불일치가 발생할 위험이 있습니다.

핵심 내용

기본적으로 서비스 워커는 성능 중립적이지 않습니다.

웹 앱에 서비스 워커를 추가한다는 것은 웹 앱이 요청에 대한 응답을 받기 전에 로드 및 실행되어야 하는 추가 JavaScript 부분을 삽입한다는 것을 의미합니다. 이러한 응답이 네트워크가 아닌 로컬 캐시에서 온다면 캐시 우선 모드로의 성능 향상에 비해 서비스 워커 실행 오버헤드가 미미한 경우가 대부분입니다. 그러나 탐색 요청을 처리할 때 서비스 워커가 항상 네트워크를 참조해야 한다는 것을 알고 있다면 탐색 미리 로드를 사용하는 것이 성능 면에서 매우 중요합니다.

서비스 워커는 (여전히!) 점진적 향상입니다

서비스 워커 지원 사례는 1년 전보다 훨씬 더 밝아졌습니다. 현재 모든 최신 브라우저는 서비스 워커 지원을 어느 정도 갖추고 있지만, 안타깝게도 백그라운드 동기화 및 탐색 미리 로드와 같은 일부 고급 서비스 워커 기능은 전체적으로 출시되지 않았습니다. 필요한 특정 기능 하위 집합의 특성을 확인하고 서비스 워커가 있을 때만 등록하는 것이 여전히 합리적인 방법입니다.

마찬가지로 실제로 실험을 진행했는데 저사양 기기의 성능이 저하되어 서비스 워커의 추가 오버헤드가 발생한다는 사실을 알고 있다면 이러한 시나리오에서도 서비스 워커를 등록하지 않아도 됩니다.

서비스 워커는 모든 기본 요건이 충족되고 서비스 워커가 사용자 환경과 전반적인 로드 성능에 긍정적인 것을 더하면 웹 앱에 추가되는 점진적 개선 기능으로 계속 취급해야 합니다.

모든 요소 측정

서비스 워커의 제공이 사용자 환경에 긍정적인 영향을 미쳤는지 부정적인 영향을 미쳤는지 판단할 수 있는 유일한 방법은 실험하고 결과를 측정하는 것입니다.

의미 있는 측정을 설정하는 방법은 사용 중인 분석 서비스 제공업체 및 배포 설정에서 일반적으로 실험을 수행하는 방법에 따라 다릅니다. Google 애널리틱스를 사용하여 측정항목을 수집하는 한 가지 접근 방식은 Google I/O 웹 앱의 서비스 워커 사용 경험을 바탕으로 한 이 우수사례에서 자세히 설명합니다.

비목표

웹 개발 커뮤니티의 상당수가 서비스 워커를 프로그레시브 웹 앱에 연결하지만, 'Google 검색 PWA' 빌드가 팀의 초기 목표는 아니었습니다. Google 검색 웹 앱은 현재 웹 앱 매니페스트를 통해 메타데이터를 제공하지 않으며 사용자에게 홈 화면에 추가 흐름을 따르도록 권장하지 않습니다. Google 검색팀은 현재 Google 검색의 기존 진입점을 통해 웹 앱을 방문하는 사용자에게 만족하고 있습니다.

Google 검색 웹 환경을 설치된 애플리케이션에서 기대하는 것과 동일한 환경으로 전환하려고 하기보다는 기존 웹사이트를 점진적으로 개선하는 데 초점을 맞췄습니다.

감사의 말

서비스 워커 구현에 참여하고 이 문서를 작성하는 데 필요한 배경 자료를 공유해 주신 Google 검색 웹 개발팀 전체에게 감사드립니다. 특히 필립 골(Rajesh Jagannathan, R. 필립 골)님께 감사드립니다. 사무엘 클라치코, 앤디 마르토네, 레오나르도 페냐, 레이첼 시어, 그렉 테로노, 클레이 울람

업데이트 (2021년 10월): 이 문서가 처음 게시된 이후 Google 검색팀에서 현재 서비스 워커 아키텍처의 이점과 절충점을 재평가했습니다. 위에서 설명한 서비스 워커가 중단됩니다. Google 검색 웹 인프라가 발전함에 따라 팀에서 서비스 워커 설계를 재검토할 수 있습니다.