Chrome 71에서 제공되는 cache.addAll() 및 importScripts()의 미세 조정

서비스 워커Cache Storage API를 사용하는 개발자는 Chrome 71에서 출시되는 두 가지 소규모 변경사항을 지켜봐야 합니다. 두 가지 변경사항으로 인해 Chrome 구현이 사양 및 다른 브라우저에 더 부합했습니다.

비동기 importScripts() 허용 안 함

importScripts()는 기본 서비스 워커 스크립트에 현재 실행을 일시중지하고 지정된 URL에서 추가 코드를 다운로드하며 현재 전역 범위에서 완료될 때까지 실행하도록 지시합니다. 완료되면 기본 서비스 워커 스크립트가 실행을 재개합니다. importScripts()는 조직적인 이유로 기본 서비스 워커 스크립트를 더 작은 조각으로 나누거나 서드 파티 코드를 가져와 서비스 워커에 기능을 추가하려는 경우에 유용합니다.

브라우저는 importScripts()를 통해 가져온 모든 항목을 자동으로 캐시하여 '동기 코드 다운로드 및 실행' 시 발생할 수 있는 성능 문제를 완화하려고 합니다. 즉, 초기 다운로드 후 가져온 코드를 실행하는 데 오버헤드가 거의 없습니다.

하지만 이렇게 하려면 브라우저가 초기 설치 후 서비스 워커에 가져온 '예기치 않은' 코드가 없음을 알아야 합니다. 서비스 워커 사양에 따라 importScripts() 호출은 최상위 서비스 워커 스크립트의 동기 실행 중에만 작동하거나 필요한 경우 install 핸들러 내에서 비동기식으로 작동해야 합니다.

Chrome 71 이전에는 install 핸들러 외부에서 importScripts()를 비동기식으로 호출해도 작동했습니다. Chrome 71부터 이러한 호출은 이전에 동일한 URL이 install 핸들러에서 가져온 경우가 아니라면 런타임 예외를 발생시켜 다른 브라우저의 동작과 일치합니다.

다음과 같은 코드 대신

// This only works in Chrome 70 and below.
self.addEventListener('fetch', event => {
  importScripts('my-fetch-logic.js');
  event.respondWith(self.customFetchLogic(event));
});

서비스 워커 코드는 다음과 같이 표시됩니다.

// Move the importScripts() to the top-level scope.
// (Alternatively, import the same URL in the install handler.)
importScripts('my-fetch-logic.js');
self.addEventListener('fetch', event => {
  event.respondWith(self.customFetchLogic(event));
});

cache.addAll()에 전달된 중복 URL 지원 중단

서비스 워커와 함께 Cache Storage API를 사용하는 경우 Chrome 71에서 관련 사양에 맞게 또 다른 사소한 변경사항이 있습니다. 동일한 URL이 cache.addAll() 호출에 여러 번 전달되면 사양에 따라 호출에서 반환된 약속이 거부되어야 합니다.

Chrome 71 이전에는 이러한 중복이 감지되지 않았으며 중복 URL은 사실상 무시되었습니다.

Chrome 콘솔의 경고 메시지 스크린샷
Chrome 71부터 콘솔에 경고 메시지가 로깅됩니다.

이 로깅은 Chrome 72의 전주곡으로, 중복 URL이 로깅된 경고 대신 cache.addAll() 거부로 이어집니다. 일반적인 관행에 따라 InstallEvent.waitUntil()에 전달된 프로미스 체인의 일부로 cache.addAll()를 호출하는 경우 거부로 인해 서비스 워커가 설치되지 않을 수 있습니다.

다음과 같은 문제가 발생할 수 있습니다.

const urlsToCache = [
  '/index.html',
  '/main.css',
  '/app.js',
  '/index.html', // Oops! This is listed twice and should be removed.
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('my-cache').then(cache => cache.addAll(urlsToCache))
  );
});

이 제한사항은 cache.addAll()에 전달되는 실제 URL에만 적용되며, '/''/index.html'와 같이 URL이 다른 동등한 두 응답을 캐시해도 거부가 트리거되지 않습니다.

광범위하게 서비스 워커 구현 테스트

이 시점에서 서비스 워커는 모든 주요 '에버그린' 브라우저에서 폭넓게 구현됩니다. 여러 브라우저에서 프로그레시브 웹 앱을 정기적으로 테스트하거나 Chrome을 사용하지 않는 사용자가 상당히 많은 경우 이미 불일치를 감지하고 코드를 업데이트했을 가능성이 큽니다. 하지만 다른 브라우저에서 이 동작을 발견하지 못하신 경우 Chrome의 동작을 전환하기 전에 변경사항을 알려드리고자 합니다.