네트워크 중심 HTML을 위한 탐색 미리 로드

서비스 워커가 fetch 이벤트를 처리하면 브라우저는 서비스 워커가 응답을 제공할 때까지 기다립니다. 네트워크 요청의 지연 시간이 대기 시간에서 큰 부분을 차지하지만 브라우저는 서비스 워커가 부팅되고 fetch 이벤트 콜백을 실행할 때까지 기다려야 할 수도 있습니다.

부팅 시간은 기기와 기능에 따라 다르지만, CPU가 느리거나 주변 조건으로 인해 제한된 상태에서 작동하는 경우에는 상당한 시간이 소요되며 경우에 따라 최대 0.5초까지 걸릴 수 있습니다. 탐색 응답이 Cache 인스턴스에서 제공되는 경우 네트워크 회피로 인한 성능 향상이 이 시작 시간보다 클 수 있습니다. 네트워크로 이동하는 탐색 요청의 경우 서비스 워커를 도입하면 체감할 수 있는 지연이 발생할 수 있습니다.

탐색 미리 로드 시작

탐색 미리 로드는 서비스 워커 부팅 시간으로 인해 발생하는 지연을 해결하는 서비스 워커 기능입니다. 탐색 미리 로드를 사용 설정하지 않으면 서비스 워커의 부팅과 서비스 워커에서 처리하는 탐색 요청이 연속적으로 발생합니다.

노란색과 파란색 막대로, 두 개의 세그먼트가 연속되는 작업을 보여줍니다. 첫 번째 세그먼트(노란색)는 'SW 부팅'으로, 파란색 세그먼트는 '탐색 요청'입니다.

이는 바람직하지 않지만 탐색 미리 로드를 사용 설정하여 문제를 해결할 수 있습니다. 이렇게 하면 서비스 워커 부팅과 탐색 요청이 동시에 발생합니다.

두 개의 막대가 나란히 쌓여 있으며 왼쪽 정렬되어 두 개의 동시 작업을 나타냅니다. 노란색 막대에는 'SW 부팅'이라는 라벨이 지정되어 있으며 파란색 막대에는 '탐색 요청'이라는 라벨이 지정되어 있습니다.

탐색 미리 로드는 서비스 워커를 사용하는 사이트에서 뛰어난 성능 최적화이지만, 모든 상황에서 사용 설정해야 하는 기능은 아닙니다. 특히 사전 캐시된 앱 셸을 사용하는 사이트는 캐시가 탐색 지연 시간 없이 앱 셸 마크업의 탐색 요청을 처리하므로 탐색 미리 로드가 필요하지 않습니다. 이러한 경우 미리 로드된 응답이 낭비되므로 이는 좋지 않습니다.

탐색 미리 로드를 사용하려면 웹사이트에서 HTML을 사전 캐시할 수 없을 때가 가장 좋습니다. 마크업 응답이 동적이며 인증 상태 등에 따라 달라지는 웹사이트를 생각해 보세요. 이러한 탐색 요청에는 네트워크 우선 (또는 네트워크 전용) 전략을 사용할 수 있으며 바로 이 때문에 탐색 미리 로드가 큰 차이를 만들 수 있습니다.

Workbox에서 탐색 미리 로드 사용

Workbox가 제공하지 않는 서비스 워커에서 직접 탐색 미리 로드를 사용하는 것은 까다롭습니다. 첫째, 일부 브라우저에서는 지원되지 않습니다. 둘째, 제대로 하기가 어려울 수 있습니다. 제이크 아치볼드의 훌륭한 설명 자료에서 직접 사용 방법을 배울 수 있습니다.

Workbox는 탐색 미리 로드 사용을 간소화합니다. workbox-navigation-preload 모듈의 enable 메서드가 필요한 기능 지원 검사를 실행하고 activate 이벤트 리스너를 만들어 사용 설정하기 때문입니다.

여기에서 탐색 미리 로드의 이점은 Workbox를 사용하여 네트워크 우선 전략 핸들러를 사용하여 탐색 요청을 처리함으로써 브라우저를 지원하는 데 실현됩니다.

import * as navigationPreload from 'workbox-navigation-preload';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {registerRoute, NavigationRoute, Route} from 'workbox-routing';
import {precacheAndRoute} from 'workbox-precaching';

// Precache the manifest
precacheAndRoute(self.__WB_MANIFEST);

// Enable navigation preload
navigationPreload.enable();

// Create a new navigation route that uses the Network-first, falling back to
// cache strategy for navigation requests with its own cache. This route will be
// handled by navigation preload. The NetworkOnly strategy will work as well.
const navigationRoute = new NavigationRoute(new NetworkFirst({
  cacheName: 'navigations'
}));

// Register the navigation route
registerRoute(navigationRoute);

// Create a route for image, script, or style requests that use a
// stale-while-revalidate strategy. This route will be unaffected
// by navigation preload.
const staticAssetsRoute = new Route(({request}) => {
  return ['image', 'script', 'style'].includes(request.destination);
}, new StaleWhileRevalidate({
  cacheName: 'static-assets'
}));

// Register the route handling static assets
registerRoute(staticAssetsRoute);

탐색 미리 로드를 사용 설정하면 Workbox는 미리 로드된 응답과 함께 NetworkFirst 또는 NetworkOnly 전략을 사용하는 탐색 요청에 응답합니다.

탐색 미리 로드가 작동하는지 어떻게 알 수 있나요?

개발 빌드에서 Workbox는 그 기능에 대한 많은 내용을 기록합니다. Workbox에서 탐색 미리 로드가 작동하는지 확인하려면 탐색을 요청하는 동안 지원 브라우저에서 콘솔을 열면 다음과 같은 로그 메시지가 표시됩니다.

Chrome DevTools 콘솔에 있는 Workbox 로그 스크린샷 '라우터가 /에 응답함', '/에 대해 미리 로드된 탐색 요청 사용 중', 'NetworkFirst를 사용하여 /에 응답' 메시지는 위에서 아래로 읽습니다.

이 로깅은 기본적으로 프로덕션 빌드에 표시되지 않으므로 서비스 워커를 프로덕션에 배포할 때는 표시되지 않지만, 탐색 미리 로드가 작동하는지 확인할 수 있는 좋은 방법입니다.

미리 로드된 응답 맞춤설정

탐색 미리 로드를 사용할 때 애플리케이션 백엔드에서 미리 로드된 응답을 맞춤설정해야 하는 시나리오가 있을 수 있습니다. 네트워크의 일부 콘텐츠를 스트리밍하는 서비스 워커가 유용한 한 가지 시나리오입니다.

이 같은 경우 미리 로드 요청이 true의 기본값이 설정된 Service-Worker-Navigation-Preload 헤더와 함께 전송된다는 것을 아는 것이 좋습니다.

Service-Worker-Navigation-Preload: true

그런 다음 선택한 애플리케이션 백엔드에서 이 헤더를 확인하고 필요에 맞게 응답을 수정할 수 있습니다. 어떤 이유로든 헤더의 기본값이 문제가 있는 경우 창 컨텍스트에서 변경할 수 있습니다. 서버에서 이 헤더를 읽기 위해 수행하는 모든 작업은 사용자의 책임이며 Workbox의 범위를 벗어납니다.

결론

탐색 미리 로드를 직접 사용할 때는 제대로 사용하기는 어렵지만, 서비스 워커가 브라우저가 탐색 요청을 하지 못하도록 막기 위해서는 그만한 가치가 있습니다. Workbox 덕분에 훨씬 적은 작업으로 탐색 미리 로드를 활용할 수 있습니다. workbox-navigation-preload 모듈에 관해 자세히 알아보려면 참조 문서를 확인하세요.