최신 서비스 워커(기본)

요약 정리

Chrome 68부터 서비스 워커 스크립트의 업데이트를 확인하는 HTTP 요청은 기본적으로 더 이상 HTTP 캐시에서 처리하지 않습니다. 이렇게 하면 서비스 워커 스크립트에 실수로 Cache-Control 헤더를 설정하여 업데이트가 지연될 수 있는 일반적인 개발자 문제를 해결할 수 있습니다.

Cache-Control: max-age=0/service-worker.js 스크립트를 제공하여 이미 /service-worker.js 스크립트의 HTTP 캐싱을 선택 해제한 경우 새 기본 동작으로 인해 변경사항이 표시되지 않습니다.

또한 Chrome 78부터 바이트 단위 비교가 importScripts()를 통해 서비스 워커에 로드된 스크립트에 적용됩니다. 가져온 스크립트를 변경하면 최상위 서비스 워커를 변경할 때와 마찬가지로 서비스 워커 업데이트 흐름이 트리거됩니다.

배경

서비스 워커의 범위 아래에 있는 새 페이지로 이동할 때마다 JavaScript에서 registration.update()를 명시적으로 호출하거나 서비스 워커가 push 또는 sync 이벤트를 통해 '깨어난' 경우 브라우저는 동시에 navigator.serviceWorker.register() 호출에 전달된 JavaScript 리소스를 요청하여 서비스 워커 스크립트의 업데이트를 찾습니다.

이 도움말에서는 URL이 /service-worker.js이고 서비스 워커 내에서 실행되는 추가 코드를 로드하는 importScripts() 호출이 한 번 포함되어 있다고 가정해 보겠습니다.

// Inside our /service-worker.js file:
importScripts('path/to/import.js');

// Other top-level code goes here.

변경되는 사항

Chrome 68 이전에는 대부분의 가져오기와 마찬가지로 /service-worker.js의 업데이트 요청이 HTTP 캐시를 통해 이루어졌습니다. 즉, 스크립트가 원래 Cache-Control: max-age=600와 함께 전송된 경우 다음 600초 (10분) 이내에 업데이트가 네트워크로 전송되지 않으므로 사용자가 최신 버전의 서비스 워커를 수신하지 못할 수 있습니다. 그러나 max-age가 86400 (24시간)보다 크면 사용자가 특정 버전에서 영원히 멈추지 않도록 86400으로 처리됩니다.

68부터 서비스 워커 스크립트 업데이트를 요청할 때 HTTP 캐시가 무시되므로 기존 웹 애플리케이션에서 서비스 워커 스크립트 요청 빈도가 증가할 수 있습니다. importScripts 요청은 계속 HTTP 캐시를 거칩니다. 하지만 이는 기본값일 뿐입니다. 이 동작을 제어할 수 있는 새 등록 옵션인 updateViaCache를 사용할 수 있습니다.

updateViaCache

이제 개발자는 navigator.serviceWorker.register()를 호출할 때 새로운 옵션인 updateViaCache 매개변수를 전달할 수 있습니다. 'imports', 'all', 'none' 중 하나의 값을 사용합니다.

이 값은 업데이트된 서비스 워커 리소스를 확인하기 위한 HTTP 요청을 할 때 브라우저의 표준 HTTP 캐시가 사용되는지 여부와 사용 방식을 결정합니다.

  • 'imports'로 설정하면 /service-worker.js 스크립트의 업데이트를 확인할 때 HTTP 캐시가 컨설트되지 않지만 가져온 스크립트(예: path/to/import.js)를 가져올 때는 컨설트됩니다. 이는 기본값이며 Chrome 68부터 시작된 동작과 일치합니다.

  • 'all'로 설정하면 최상위 /service-worker.js 스크립트와 서비스 작업자 내부에서 가져온 모든 스크립트(예: path/to/import.js)를 요청할 때 HTTP 캐시가 컨설트됩니다. 이 옵션은 Chrome 68 이전의 Chrome에서의 이전 동작에 해당합니다.

  • 'none'로 설정하면 최상위 /service-worker.js 또는 가상의 path/to/import.js와 같은 가져온 스크립트에 대해 요청할 때 HTTP 캐시가 컨설트되지 않습니다.

예를 들어 다음 코드는 서비스 워커를 등록하고 /service-worker.js 스크립트 또는 /service-worker.js 내에서 importScripts()를 통해 참조되는 스크립트의 업데이트를 확인할 때 HTTP 캐시를 참조하지 않도록 합니다.

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js', {
    updateViaCache: 'none',
    // Optionally, set 'scope' here, if needed.
  });
}

가져온 스크립트의 업데이트를 확인합니다.

Chrome 78 이전에는 importScripts()를 통해 로드된 모든 서비스 워커 스크립트가 한 번만 검색되었습니다 (updateViaCache 구성에 따라 먼저 HTTP 캐시를 확인하거나 네트워크를 통해 확인). 이 초기 검색 후에는 브라우저에 내부적으로 저장되며 다시 가져오지 않습니다.

이미 설치된 서비스 워커가 가져온 스크립트의 변경사항을 강제로 선택하도록 하는 유일한 방법은 일반적으로 semver 값 (예: importScripts('https://example.com/v1.1.0/index.js'))을 추가하거나 콘텐츠의 해시 (예: importScripts('https://example.com/index.abcd1234.js'))를 포함하여 스크립트의 URL을 변경하는 것이었습니다. 가져온 URL을 변경하면 최상위 서비스 워커 스크립트의 콘텐츠가 변경되어 서비스 워커 업데이트 흐름이 트리거됩니다.

Chrome 78부터 최상위 서비스 워커 파일에 대한 업데이트 확인이 실행될 때마다 가져온 스크립트의 콘텐츠가 변경되었는지 확인하는 검사가 동시에 실행됩니다. 사용되는 Cache-Control 헤더에 따라 이러한 가져온 스크립트 검사는 updateViaCache'all' 또는 'imports' (기본값)으로 설정된 경우 HTTP 캐시에서 처리되거나 updateViaCache'none'로 설정된 경우 네트워크에 직접 연결될 수 있습니다.

가져온 스크립트의 업데이트 확인 결과가 이전에 서비스 워커에 저장된 것과 바이트 단위로 차이가 있으면 최상위 서비스 워커 파일이 동일하게 유지되더라도 전체 서비스 워커 업데이트 흐름이 트리거됩니다.

Chrome 78 동작은 몇 년 전 Firefox 56에서 Firefox가 구현한 것과 일치합니다. Safari에서는 이미 이 동작을 구현하고 있습니다.

개발자는 무엇을 해야 하나요?

Cache-Control: max-age=0 (또는 유사한 값)을 사용하여 /service-worker.js 스크립트를 제공하여 /service-worker.js 스크립트의 HTTP 캐싱을 선택 해제한 경우 새 기본 동작으로 인해 변경사항이 표시되지 않습니다.

의도적으로 또는 호스팅 환경의 기본값이기 때문에 HTTP 캐싱을 사용 설정하여 /service-worker.js 스크립트를 제공하는 경우 서버에 대해 이루어진 /service-worker.js의 추가 HTTP 요청이 증가할 수 있습니다. 이러한 요청은 이전에 HTTP 캐시에서 처리하던 요청입니다. Cache-Control 헤더 값이 /service-worker.js의 최신성에 계속 영향을 미치도록 허용하려면 서비스 워커를 등록할 때 updateViaCache: 'all'를 명시적으로 설정해야 합니다.

이전 브라우저 버전의 사용자가 많을 수 있으므로 최신 브라우저에서 무시할 수 있지만 서비스 워커 스크립트에서 Cache-Control: max-age=0 HTTP 헤더를 계속 설정하는 것이 좋습니다.

개발자는 이 기회를 사용하여 가져온 스크립트를 지금 HTTP 캐싱에서 제외할지 여부를 명시적으로 선택하고 적절한 경우 서비스 워커 등록에 updateViaCache: 'none'를 추가할 수 있습니다.

가져온 스크립트 제공

Chrome 78부터는 importScripts()를 통해 로드된 리소스에 대한 업데이트가 확인되므로 개발자에게 더 많은 수신 HTTP 요청이 표시될 수 있습니다.

이러한 추가 HTTP 트래픽을 피하려면 URL에 semver 또는 해시가 포함된 스크립트를 제공할 때 장기 Cache-Control 헤더를 설정하고 'imports'의 기본 updateViaCache 동작을 사용하세요.

또는 가져온 스크립트가 자주 업데이트되는지 확인하려면 Cache-Control: max-age=0로 제공하거나 updateViaCache: 'none'를 사용하세요.

추가 자료

Jake Archibald의 'Service Worker 수명 주기' 및 '캐싱 권장사항 및 max-age 문제'는 웹에 배포하는 모든 개발자에게 권장되는 자료입니다.