Обработка запросов навигации

Отвечайте на запросы навигации, не дожидаясь сети, с помощью сервис-воркера.

Навигационные запросы — это запросы HTML-документов, выполняемые вашим браузером всякий раз, когда вы вводите новый URL-адрес на панели навигации или переходите по ссылке на странице, ведущей на новый URL-адрес. Именно здесь сервис-воркеры оказывают наибольшее влияние на производительность: если вы используете сервис-воркера для ответа на запросы навигации, не дожидаясь сети, вы можете гарантировать, что навигация будет надежно быстрой, а также устойчивой, когда сеть недоступна. Это самый большой выигрыш в производительности, достигнутый сервисным работником, по сравнению с тем, что возможно с помощью HTTP-кэширования .

Как подробно описано в разделе «Определение ресурсов, загружаемых из руководства по сети» , запрос навигации — это первый из потенциально многих запросов, выполняемых в «водопаде» сетевого трафика. HTML-код, который вы загружаете с помощью запроса навигации, запускает поток всех других запросов к подресурсам, таким как изображения, сценарии и стили.

Внутри обработчика событий fetch сервис-воркера вы можете определить, является ли запрос навигацией, проверив свойство request.mode в FetchEvent . Если для него установлено значение 'navigate' , то это запрос навигации.

Как правило, не используйте долгоживущие Cache-Control headers для кэширования ответа HTML на запрос навигации. Обычно их следует выполнять через сеть с помощью Cache-Control: no-cache , чтобы гарантировать, что HTML вместе с цепочкой последующих сетевых запросов является (достаточно) свежим. К сожалению, нарушение сети каждый раз, когда пользователь переходит на новую страницу, означает, что каждая навигация может быть медленной. По крайней мере, это означает, что он не будет надежно быстрым.

Различные подходы к архитектуре

Выяснить, как реагировать на запросы навигации, избегая при этом сети, может быть непросто. Правильный подход во многом зависит от архитектуры вашего веб-сайта и количества уникальных URL-адресов, по которым могут перейти пользователи.

Хотя универсального решения не существует, следующие общие рекомендации помогут вам решить, какой подход является наиболее жизнеспособным.

Небольшие статические сайты

Если ваше веб-приложение состоит из относительно небольшого количества (подумайте: пара десятков) уникальных URL-адресов, и каждый из этих URL-адресов соответствует отдельному статическому HTML-файлу, то один из жизнеспособных подходов — просто кэшировать все эти HTML-файлы и отвечать на них. к запросам навигации с соответствующим кэшированным HTML.

Используя предварительное кэширование , вы можете кэшировать HTML заранее, как только будет установлен сервис-воркер, и обновлять кэшированный HTML каждый раз, когда вы перестраиваете свой сайт и повторно развертываете сервис-воркера.

В качестве альтернативы, если вы предпочитаете избегать предварительного кэширования всего HTML-кода (возможно, потому, что пользователи склонны переходить только к подмножеству URL-адресов на вашем сайте), вы можете использовать стратегию кэширования устаревшего кода во время повторной проверки . Однако будьте осторожны с этим подходом, поскольку каждый отдельный HTML-документ кэшируется и обновляется отдельно. Использование кэширования во время выполнения HTML наиболее целесообразно, если у вас небольшое количество URL-адресов, которые часто посещаются одним и тем же набором пользователей, и если вы чувствуете себя комфортно, если эти URL-адреса проверяются независимо друг от друга.

Одностраничные приложения

Одностраничная архитектура часто используется в современных веб-приложениях. В нем клиентский JavaScript изменяет HTML в ответ на действия пользователя. Эта модель использует API истории для изменения текущего URL-адреса при взаимодействии пользователя с веб-приложением, что фактически приводит к «моделированной» навигации. Хотя последующие переходы могут быть «фальшивыми», первоначальная навигация реальна, и все равно важно убедиться, что она не заблокирована в сети.

К счастью, если вы используете одностраничную архитектуру, существует простой шаблон для обслуживания начальной навигации из кэша: оболочка приложения . В этой модели ваш сервис-воркер отвечает на запросы навигации, возвращая один и тот же HTML-файл, который уже был предварительно кэширован, независимо от запрашиваемого URL-адреса. Этот HTML-код должен быть простым, состоящим, возможно, из общего индикатора загрузки или скелетного содержимого . Как только браузер загрузит этот HTML-код из кеша, существующий клиентский JavaScript возьмет на себя управление и отобразит правильное HTML-содержимое для URL-адреса из исходного навигационного запроса.

Workbox предоставляет инструменты, необходимые для реализации этого подхода; navigateFallback option позволяет вам указать, какой HTML-документ использовать в качестве оболочки вашего приложения, а также необязательный список разрешений и запретов, чтобы ограничить это поведение подмножеством ваших URL-адресов.

Многостраничные приложения

Если ваш веб-сервер динамически генерирует HTML-код вашего сайта или у вас более нескольких десятков уникальных страниц, тогда гораздо сложнее избежать сети при обработке навигационных запросов. Советы из раздела «Все остальное» , скорее всего, применимы и к вам.

Но для определенного подмножества многостраничных приложений вы можете реализовать сервис-воркера, который полностью копирует логику, используемую на вашем веб-сервере для генерации HTML. Это работает лучше всего, если вы можете обмениваться информацией о маршрутизации и шаблонах между сервером и средой Service Worker, и, в частности, если ваш веб-сервер использует JavaScript (не полагаясь на специфичные для Node.js функции, такие как доступ к файловой системе).

Если ваш веб-сервер попадает в эту категорию и вы хотели бы изучить один из подходов к переносу генерации HTML из сети в ваш сервис-воркер, руководство в разделе «За пределами SPA: альтернативные архитектуры для вашего PWA» может помочь вам начать работу.

Все остальное

Если вы не можете отвечать на запросы навигации с помощью кэшированного HTML, вы должны принять меры, чтобы добавление сервисного работника на ваш сайт (для обработки других, не HTML-запросов) не замедляло вашу навигацию. Запуск Service Worker без его использования для ответа на запрос навигации приведет к небольшой задержке (как описано в разделе «Создание более быстрых и отказоустойчивых приложений с помощью Service Worker »). Вы можете уменьшить эти накладные расходы, включив функцию, называемую предварительной загрузкой навигации , а затем используя ответ сети , предварительно загруженный в обработчик событий fetch .

Workbox предоставляет вспомогательную библиотеку , которая определяет, поддерживается ли предварительная загрузка навигации, и если да, то упрощает процесс указания сервисному работнику использовать ответ сети.

Фото Аарона Бердена на Unsplash