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

출시된 항목, 영향 측정 방법, 이루어진 절충에 관한 이야기입니다.

게시일: 2019년 6월 20일

Google에서 거의 모든 주제를 검색하면 의미 있고 관련성 있는 결과가 즉시 인식 가능한 페이지에 표시됩니다. 이 검색 결과 페이지는 특정 시나리오에서 서비스 워커라는 강력한 웹 기술에 의해 제공됩니다.

성능에 부정적인 영향을 주지 않고 Google 검색에 서비스 워커 지원을 출시하려면 여러 팀에서 수십 명의 엔지니어가 작업해야 했습니다. 이는 출시된 항목, 성능 측정 방법, 이루어진 절충에 관한 이야기입니다.

서비스 워커를 살펴봐야 하는 주요 이유

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

제한된 검색 결과 캐싱

Google 검색팀은 사용자가 짧은 시간 내에 동일한 검색어를 두 번 이상 검색하는 경우가 많다는 것을 확인했습니다. 검색팀은 동일한 결과가 나올 가능성이 높은 결과를 얻기 위해 새 백엔드 요청을 트리거하는 대신 캐싱을 활용하여 이러한 반복 요청을 로컬에서 처리하고자 했습니다.

최신성은 매우 중요하며, 때로는 사용자가 진화하는 주제이기 때문에 동일한 검색어를 반복적으로 검색하고 최신 결과를 기대합니다. 서비스 워커를 사용하면 Google 검색팀이 로컬에 캐시된 검색 결과의 수명을 제어하는 세부적인 로직을 구현하고 사용자를 가장 잘 지원한다고 생각하는 속도와 최신성의 정확한 균형을 달성할 수 있습니다.

의미 있는 오프라인 환경

또한 Google 검색팀은 의미 있는 오프라인 환경을 제공하고자 했습니다. 사용자는 주제에 대해 알아볼 때 활성 인터넷 연결에 대해 걱정하지 않고 Google 검색 페이지로 바로 이동하여 검색을 시작하기를 원합니다.

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

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

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

더 스마트한 JavaScript 캐싱 및 제공

또 다른 동기는 검색 결과 페이지의 다양한 유형의 기능을 지원하는 모듈화된 JavaScript 코드의 캐싱 및 로딩을 최적화하는 것이었습니다. 서비스 워커가 관여하지 않을 때 유용한 JavaScript 번들링의 이점이 많으므로 검색팀은 번들링을 완전히 중단하고 싶지 않았습니다.

서비스 워커가 런타임에 세부적인 JavaScript 청크를 버전 관리하고 캐시하는 기능을 사용하면 캐시 변동량을 줄이고 향후 재사용되는 JavaScript를 효율적으로 캐시할 수 있다고 검색팀은 생각했습니다. 서비스 워커 내부의 로직은 여러 JavaScript 모듈이 포함된 번들의 아웃바운드 HTTP 요청을 분석하고 로컬에 캐시된 여러 모듈을 조합하여 이를 처리할 수 있습니다. 즉, 가능한 경우 '번들 해제'를 효과적으로 수행할 수 있습니다. 이렇게 하면 사용자 대역폭이 절약되고 전반적인 응답성이 개선됩니다.

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

도전과제 및 솔루션

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

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

Google 검색에서 서비스 워커를 실행할 때 가장 큰 문제이자 진정한 차단 요소는 사용자 인지 지연 시간을 늘릴 수 있는 작업을 하지 않도록 하는 것이었습니다. Google 검색은 성능을 매우 중요하게 생각하며, 과거에는 특정 사용자 집단에 수십 밀리초의 추가 지연 시간이 발생하더라도 새 기능의 출시를 차단했습니다.

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

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

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

이로 인해 서비스 워커 구현의 지연 시간이 너무 길어져 다른 이점을 정당화할 수 없습니다. 또한 실제 기기에서 서비스 워커 부팅 시간을 측정한 결과, 시작 시간이 광범위하게 분포되어 있으며 일부 저가형 모바일 기기에서는 서비스 워커를 시작하는 데 결과 페이지의 HTML에 대한 네트워크 요청을 하는 데 걸리는 시간과 거의 동일한 시간이 걸리는 것으로 나타났습니다.

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

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

탐색 요청과 병렬로 실행되는 SW 시작을 보여주는 그림

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

또한 검색팀은 서비스 워커 부팅 시간이 탐색 요청을 초과할 수 있는 로우엔드 모바일 기기에서 서비스 워커를 사용하지 않아야 했습니다. '엔트리급' 기기를 구성하는 요소에 관한 명확한 규칙이 없으므로 기기에 설치된 총 RAM을 확인하는 휴리스틱을 고안했습니다. 메모리가 2GB 미만인 기기는 서비스 워커 시작 시간이 허용되지 않는 하위 기기 카테고리에 속했습니다.

향후 사용을 위해 캐시할 리소스 전체 집합이 수 메가바이트에 달할 수 있으므로 사용 가능한 저장공간도 고려해야 합니다. navigator.storage 인터페이스를 사용하면 Google 검색 페이지에서 데이터 캐시 시도가 스토리지 할당량 실패로 인해 실패할 위험이 있는지 미리 파악할 수 있습니다.

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

이 선택적 등록의 한 가지 부수적인 이점은 더 작고 효율적인 서비스 워커를 제공할 수 있다는 것입니다. 서비스 워커 코드를 실행할 대상으로 비교적 최신 브라우저를 타겟팅하면 이전 브라우저의 트랜스파일 및 폴리필 오버헤드가 제거됩니다. 결과적으로 서비스 워커 구현의 총 크기에서 압축되지 않은 JavaScript 코드 약 8KB가 잘려 나갔습니다.

문제: 서비스 워커 범위

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

범위 지정은 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를 사용하여 쿠키 전송

실험용 API가 출시되어 서비스 워커 내에서 브라우저의 쿠키에 직접 액세스할 수 있을 때까지 기다리는 대신 Google 검색팀은 임시 해결책을 선택했습니다. 서비스 워커로 제어되는 페이지가 로드될 때마다 페이지는 관련 쿠키를 읽고 postMessage()를 사용하여 서비스 워커로 전송합니다.

그런 다음 서비스 워커는 현재 쿠키 값을 예상 값과 비교하고 불일치가 있으면 스토리지에서 사용자별 데이터를 삭제하고 잘못된 맞춤설정 없이 검색 결과 페이지를 다시 로드하는 단계를 실행합니다.

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

문제: 실험 및 동적

앞서 언급한 바와 같이 Google 검색팀은 프로덕션에서 실험을 실행하고, 기본적으로 사용 설정하기 전에 실제 환경에서 새 코드와 기능의 효과를 테스트하는 데 크게 의존합니다. 사용자를 실험에 참여시키거나 참여를 중단시키는 데 백엔드 서버와의 통신이 필요한 경우가 많으므로 캐시된 데이터를 많이 사용하는 정적 서비스 워커의 경우 이 문제가 다소 어려울 수 있습니다.

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

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

동적으로 생성된 서비스 워커 스크립트를 사용하면 서비스 워커 구현에 피해야 하는 심각한 버그가 있는 드문 경우에 이스케이프 해치를 더 쉽게 제공할 수 있습니다. 동적 서버 워커 응답은 작업 없음 구현일 수 있으며, 이는 일부 또는 모든 현재 사용자에 대해 서비스 워커를 효과적으로 사용 중지합니다.

문제: 업데이트 조정

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

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

서비스 워커를 실험하는 동안 Google 검색팀은 측정항목과 사용자 환경이 재방문 사용자가 실제 환경에서 보게 될 내용과 더 일치하도록 여러 예약된 백엔드 업데이트에서 실험이 계속 실행되도록 했습니다.

솔루션: 업데이트 빈도와 캐시 활용의 균형

다양한 구성 옵션을 테스트한 결과 Google 검색팀은 다음 설정이 최신성과 캐시 활용 간의 적절한 균형을 제공한다는 것을 확인했습니다.

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

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

또한 서비스 워커 스크립트의 HTTP 응답에 ETag 헤더가 설정되어 25분이 지난 후 업데이트 확인이 이루어질 때 중간에 배포된 서비스 워커가 업데이트되지 않은 경우 서버가 HTTP 304 응답으로 효율적으로 응답할 수 있습니다.

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

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

핵심 요점

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

웹 앱에 서비스 워커를 추가한다는 것은 웹 앱이 요청에 대한 응답을 받기 전에 로드되고 실행되어야 하는 추가 JavaScript를 삽입한다는 의미입니다. 이러한 응답이 네트워크가 아닌 로컬 캐시에서 제공되는 경우 서비스 워커 실행 오버헤드는 일반적으로 캐시 우선으로 인한 성능 이점에 비해 미미합니다. 하지만 서비스 워커가 탐색 요청을 처리할 때 항상 네트워크를 참조해야 한다면 탐색 미리 로드를 사용하는 것이 성능에 매우 중요합니다.

서비스 워커는 여전히 점진적 개선입니다.

서비스 워커 지원은 1년 전보다 훨씬 밝아졌습니다. 이제 모든 최신 브라우저에서 최소한 서비스 워커 지원을 제공하지만, 아쉽게도 백그라운드 동기화 및 탐색 미리 로드와 같은 일부 고급 서비스 워커 기능은 보편적으로 출시되지 않습니다. 필요한 기능의 특정 하위 집합을 확인하고 이러한 기능이 있는 경우에만 서비스 워커를 등록하는 것은 여전히 합리적인 접근 방식입니다.

마찬가지로 실제 환경에서 실험을 실행했고 서비스 워커의 추가 오버헤드로 인해 로우엔드 기기의 성능이 저하된다는 것을 알고 있다면 이러한 시나리오에서 서비스 워커를 등록하지 않아도 됩니다.

모든 필수 요건이 충족되고 서비스 워커가 사용자 환경과 전반적인 로드 성능에 긍정적인 영향을 미치는 경우 서비스 워커를 웹 앱에 추가되는 점진적 개선으로 취급해야 합니다.

모든 항목 측정

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

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

목표가 아닌 항목

웹 개발 커뮤니티의 많은 사용자가 서비스 워커를 프로그레시브 웹 앱과 연관시키지만, 'Google 검색 PWA'를 빌드하는 것은 팀의 초기 목표가 아니었습니다. Google 검색 웹 앱은 웹 앱 매니페스트에 메타데이터를 제공하지 않으며 사용자가 홈 화면에 추가 흐름을 거치도록 유도하지도 않습니다. 검색팀은 사용자가 Google 검색의 기존 진입점을 통해 웹 앱에 도달하는 데 만족합니다.

Google 검색 웹 환경을 설치된 애플리케이션에서 기대하는 것과 동일하게 만들려고 하는 대신 초기 출시에서는 기존 웹사이트를 점진적으로 개선하는 데 중점을 두었습니다.

감사의 말씀

서비스 워커 구현에 힘써 주시고 이 글을 쓰는 데 필요한 배경 자료를 공유해 주신 Google 검색 웹 개발팀 전체에 감사드립니다. 특히 Philippe Golle, Rajesh Jagannathan, R. 사무엘 클라치코, 앤디 마르토네, 레오나르도 페냐, 레이첼 셰어러, 그레그 테로노, 클레이 울람

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