Service worker Navigation PreLoad

unu·2021년 7월 9일
0
post-thumbnail

tmdb api에서 지원되는 비디오들의 유튜브 키를 변수로 받아서 로드 하는데 자꾸 아래와 같은 에러가 떠서 찾아봤다.

출처 https://love2dev.com/pwa/service-worker-preload/

서비스 워커에서 브라우저 힌트 PreLoad 지원을 활성화하여 페이지 속도 향상시키는 법

Article by. Chris Love

서론

사이트의 페이지 속도를 향상시키기 위한 많은 미묘한 트릭이 있습니다. 고급 기술 중 하나는 여기에서 읽을 수 있는 브라우저 힌트를 사용하는 것입니다.

이러한 브라우저 힌트 중 하나는 'preload'로, 브라우저가 일반적으로 마크업의 위치로 인해 리소스 로드를 시작하는 시점보다 일찍 리소스 로드를 시작합니다.

예를 들어 스크립트, 이미지 및 기타 리소스를 일찍 로드할 수 있습니다. 이것은 콘텐츠가 처리된다는 의미가 아니라 단지 네트워크 요청을 시작한다는 의미입니다.

사전 로드 힌트와 서비스 워커를 사용할 때 문제가 발생할 수 있습니다. 서비스 워커는 네트워크 요청을 처리하기 전에 '부팅'해야 합니다.


서비스 워커 생명주기

서비스 워커는 연중 무휴 24 시간 운영되지 않습니다. 그렇게한다면 기기 배터리를 소모하고 추가 CPU주기를 소모 할 수 있습니다. 이렇게 하면 컴퓨터나 모바일 장치의 속도가 느려질 뿐만 아니라 사용자가 장치를 계속 충전해야 합니다.
대신 서비스 작업자는 사용되지 않을 때 AWS Lambda 또는 Azure 기능과 마찬가지로 휴면 상태가 됩니다.
사용자가 사이트를 실행하고 있더라도 일정 시간 동안 서비스 작업자를 사용하지 않으면 브라우저는 필요할 때까지 자동으로 사이트를 끕니다.

이는 서비스 작업자가 시작하기를 기다리는 동안 사전 로드의 효과가 손실될 수 있음을 의미합니다. 문제를 완화하기 위해 일부 브라우저에서는 서비스 워커에서 사전 로드 지원을 활성화할 수 있도록 허용하기 시작했습니다.


서비스 워커 및 Preload 문제

사이트의 서비스 워커가 활성 상태가 아니라고 가정하면 사전 로드 네트워크 요청이 차단되어 서비스 워커가 부팅되기를 기다릴 수 있습니다.


Normal Service Worker Boot Sequence

웹 사이트의 전체 페이지 속도 프로필을 개선하더라도 캐싱을 통해 네트워크 대기 시간을 개선하려면 서비스 작업자가 실행 중이어야 합니다.

서비스 워커는 운영 체제나 기본 앱처럼 부팅해야 합니다. 이 부팅 시간은 일반적으로 더 높은 전원 장치에서 50ms 이하로 빠릅니다. 그러나 저렴한 모바일 핸드셋에서는 250ms까지 걸릴 수 있습니다.

이제 서비스 워커가 활성 상태가 아니면 사전 로드 요청이 서비스 워커 프로세스와 병렬로 진행됩니다.

이는 또한 서비스 워커가 네트워크 요청이 preload 될 가능성을 고려해야 함을 의미합니다. 즉, fetch event handler logic가 이 시나리오를 처리해야 합니다.

Chrome 버전 59(오래 전)부터 서비스 워커 navigationPreload 기능이 기본적으로 지원되었습니다.

이렇게 하면 GET 요청이 서비스 워커 부팅과 동시에 진행될 수 있습니다.


Service Worker Preload Boot


서비스 워커 Navigation Preload 에러 메시지

Chromium 기반 브라우저에서 서비스 워커 navigationPreload 배관을 사용하지 않고 사전 로드 브라우저 힌트를 사용하는 경우 브라우저 콘솔에 다음 오류 메시지가 표시될 가능성이 큽니다.

The service worker navigation preload request was cancelled before 'preloadResponse' settled. If you intend to use 'preloadResponse', use waitUntil() or respondWith() to wait for the promise to settle.


서비스 워커 탐색 사전 로드 요청이 'preloadResponse'가 해결되기 전에 취소되었습니다. 'preloadResponse'를 사용하려면 waitUntil() 또는 respondWith()를 사용하여 promise가 해결될 때까지 기다리십시오.

서비스 워커가 부팅되기 전에 사전 로드 요청이 시도될 때 트리거됩니다.

브라우저는 서비스 워커가 부팅이 완료되기 전에 네트워크 요청을 고려하지 않았기 때문에 사전로드 요청이 효과적으로 차단되었음을 알려줍니다.

또한 서비스 워커 페치 이벤트 핸들러가 사용 가능한 preloadResponse를 사용하고 있지 않음을 의미합니다.


Service Worker Navigation Preload 지원 확인

모든 브라우저가 service worker navigation preload기능을 지원하는 것은 아니므로 기능 감지를 사용하여 API를 사용할 수 있는지 확인해야 합니다.

navigation preLoad 지원, 활성화 및 가져오기(fetch)를 활성화하기 위해 연결해야하는 두 가지 방법이 있습니다.

서비스 작업자 활성화 이벤트에서 navigationPreload 객체에 대한 기능 감지를 수행해야 합니다.

navigationPreload 객체는 서비스 워커 Registration 객체의 멤버입니다.

self.addEventListener( "activate", event => { event.waitUntil( async function () { // Feature-detect if ( self.registration.navigationPreload ) { // Enable navigation preloads! console.log( "Enable navigation preloads!" ); await self.registration.navigationPreload.enable(); } return; } ) }() );} );

서비스 워커 등록 개체에 navigationPreload 멤버가 포함되어 있으면 해당 enable 메서드를 안전하게 호출할 수 있습니다.

이렇게 하면 fetch event handler에 대한 기능이 켜집니다. disable 메소드를 호출하여 preFetch 지원을 끌 수도 있습니다.

enable 및 disable 메소드는 모두 promise을 반환합니다. 서비스 워커의 모든 것은 비동기식이어야 함을 기억하십시오.

promise 스택으로 작업하는 대신 await 속성을 사용하여 이를 동기 메서드로 효과적으로 전환할 수 있습니다. 어떤 방법도 값을 확인하지 않습니다.

또한 이것은 responseWith 메소드 내에서 수행되어야 합니다. 이 방법에 익숙하지 않은 경우 모든 기능이 완료될 때까지 이벤트 처리기 문이 열린 상태로 유지됩니다


서비스 워커 fetch Event Handler에서 preFetch Requests 지원

이제 서비스 워커에서 사전 로드 응답이 활성화되었으므로 fetch 이벤트 핸들러도 응답을 고려해야 합니다.

이렇게하려면 처리 논리에 preloadResponse를 잡기위한 지원을 추가해야합니다.

//출처사이트의 설명
addEventListener("fetch", event => { 
  event.respondWith(async function() {
    // Respond from the cache if we can
    const cachedResponse = await caches.match(event.request);
    if (cachedResponse) return cachedResponse; 
    // Else, use the preloaded response, if it's there 
    const response = await event.preloadResponse;
    if (response) return response;
    // Else try the network. 
    return fetch(event.request);
  }());
});

--------------------------------------------------------

//MDN MOZILLA의 설명
addEventListener('fetch', event => {
    // Prevent the default, and handle the request ourselves.
    event.respondWith(async function() {
      // Try to get the response from a cache.
      const cachedResponse = await caches.match(event.request);
      // Return it if we found one.
      if (cachedResponse) return cachedResponse;
      // If we didn't find a match in the cache, use the network.
      return fetch(event.request);
    }());
  });

서비스 워커 캐시 내에서 일치 항목을 찾는 것과 마찬가지로 preloadResponse는 비동기적이며 응답 개체를 반환합니다.

위는 표준 서비스 워커 캐시가 먼저이고 네트워크 패턴입니다. 이제 패턴은 preloadResponse에 대한 지원을 추가합니다.

물론 캐시된 응답을 사용할 수 있는 경우 최소한 대부분의 경우 먼저 이를 반환해야 합니다. 네트워크 요청을 수행하기 전에 사전 로드 요청이 유효한 응답으로 트리거되었는지 확인하십시오.

그냥 일반 fetch를 사용하지 않는 이유는 뭘까요?

글쎄요, 복잡하고, 브라우저 배관을 파헤쳐야 합니다. 이것은 실제로 가치가 없으므로 소화하기 쉬운 상위 수준을 살펴보겠습니다.

브라우저가 사전 로드 요청을 시작하면 백그라운드에서 수행됩니다. 이는 요청이 이미 시작되었음을 의미합니다.

새 가져오기 요청을 하면 리소스가 네트워크를 통해 두 번 요청된다는 의미입니다. 이것은 우리가 피해야 하는 것입니다.

preloadResponse는 일종의 특별한 백그라운드 대기 응답으로 생각할 수 있습니다. 있을 수도 있고 없을 수도 있습니다. 어느 쪽이든 요청이 완료되는 즉시 응답이 (비동기적으로) 해결됩니다.

요청이 preload 힌트에 의해 시작되지 않은 경우 메서드는 정의되지 않은 응답 개체로 즉시 해결됩니다. 즉, 자연스럽게 네트워크 요청 가져오기로 대체됩니다.


요약

Service worker Navigation Preload API는 브라우저 콘솔에서 오류 또는 경고 메시지에 나타나며 주목받았습니다. 한편, Microsoft Edge 엔지니어 중 한 명이 어느 날 우리가 몇 가지를 검토하는 동안 저에게 지적했습니다.

이 API를 사용하지 않으면 사전에 문제가 발생하지 않지만 서비스 작업자에서 구현해야 합니다.

이렇게 하면 서비스 워커 부팅 시퀀스에 의해 무효화되지 않고 페이지에서 브라우저 힌트 preload 기능을 활용할 수 있습니다.

다시 말하지만 이것은 사이트의 서비스 워커를 생성할 때 알고 있어야 하는 작은 기능 중 하나입니다.

이는 우수한 서비스 작업자를 확보하고 이들이 제공하는 성능 이점을 최대한 활용할 수 있도록 관리해야 하는 많은 시나리오 및 기능의 한 예일 뿐입니다.

profile
나 미대 나온 개발자야~

0개의 댓글