Navigation Preload — это технология, которая позволяет ускорять загрузку страниц при работе с сервис-воркерами. Она решает проблему задержки, возникающую при сетевых запросах, когда браузер ждет активации сервис-воркера перед отправкой запроса к серверу. Workbox предоставляет удобный API для включения и управления этой функцией.
Асинхронная загрузка ресурсов При обычной работе сервис-воркера навигационный запрос блокируется до его активации. Navigation Preload позволяет браузеру отправлять сетевой запрос параллельно с активацией сервис-воркера, что уменьшает задержку первого ответа.
Интеграция с Workbox Workbox облегчает настройку
Navigation Preload через модуль workbox-core. Его методы
позволяют включать и управлять предзагрузкой без написания
низкоуровневого кода.
Для активации Navigation Preload используется метод
enable() объекта navigationPreload
сервис-воркера:
import { setCacheNameDetails } from 'workbox-core';
self.addEventListener('activate', (event) => {
event.waitUntil(
(async () => {
if (self.registration.navigationPreload) {
await self.registration.navigationPreload.enable();
}
})()
);
});
Ключевые моменты:
self.registration.navigationPreload
необходима для обеспечения совместимости с браузерами, которые не
поддерживают API.activate, чтобы
гарантировать, что сервис-воркер полностью установлен и готов к
обработке запросов.После активации Navigation Preload можно получать результаты
предзагрузки внутри события fetch:
self.addEventListener('fetch', (event) => {
if (event.request.mode === 'navigate') {
event.respondWith(
(async () => {
try {
const preloadResponse = await event.preloadResponse;
if (preloadResponse) {
return preloadResponse;
}
return fetch(event.request);
} catch (error) {
return caches.match('/offline.html');
}
})()
);
}
});
Особенности работы:
event.preloadResponse возвращает промис с ответом
сервера, полученным параллельно с активацией сервис-воркера.fetch.catch можно использовать кэшированные данные
для оффлайн-режима.Workbox позволяет комбинировать Navigation Preload с стратегиями
кэширования. Например, можно использовать стратегию
NetworkFirst для страниц навигации, используя
предзагруженный ответ:
import { registerRoute } from 'workbox-routing';
import { NetworkFirst } from 'workbox-strategies';
registerRoute(
({ request }) => request.mode === 'navigate',
new NetworkFirst({
cacheName: 'pages-cache',
plugins: [],
fetchOptions: {
// Предзагруженный ответ будет автоматически использован
},
})
);
Преимущества такого подхода:
Navigation Preload можно использовать вместе с кэш-плагинами Workbox для оптимизации производительности:
CacheFirst для статических ресурсов, загружаемых
параллельно с предзагрузкой навигации.NetworkFirst для HTML-страниц, чтобы пользователи
получали актуальный контент, но при этом имели fallback в кэше.Пример комбинированного использования:
import { CacheFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';
registerRoute(
({ request }) => request.destination === 'script' || request.destination === 'style',
new CacheFirst({
cacheName: 'assets-cache',
plugins: [
new ExpirationPlugin({
maxEntries: 50,
maxAgeSeconds: 7 * 24 * 60 * 60, // неделя
}),
],
})
);
self.registration.navigationPreload.