Отслеживание сетевой активности и переходов между страницами в SPA
При создании инъецируемых скриптов для сайтов, использующих архитектуру SPA (Single Page Application), может возникнуть потребность отслеживать переходы между страницами или перезагрузки элементов. Из-за динамической подгрузки контента через AJAX и Fetch, события DOMContentLoaded или load будут бесполезны.
Для инъецируемых скриптов, хорошим решением будет отслеживать состояние радиомолчания (network idle). Оно наступает, когда все сетевые запросы завершены, и сеть на некоторое время «замолкает». Подобное поведение полезно, если нужно запустить код только после того, как пройдут все запросы или после перехода на другую страницу, чтобы реинициализировать скрипт.
💻 Пример сценария использования
Представьте себе, что вы хотите внедрить кнопки, виджет или другую логику на странице, которая должна запускаться после перехода на новую страницу в SPA-приложении. В этом случае подойдет отслеживание network-idle, чтобы понять, когда контент страницы загрузился.
🤫 Как это работает
Инициализация счетчика активных сетевых запросов.
Сниппет отслеживает все сетевые запросы на странице (Fetch и XMLHttpRequest) с помощью PerformanceObserver. Каждый раз, когда начинается новый сетевой запрос, счетчик activeRequests увеличивается.
Обработка завершения запросов.
После завершения запроса activeRequests уменьшается, и проверяется состояние сети. Если активных запросов не осталось, через 500 мс на объекте window генерируется событие network-idle.
Использование события network-idle.
На это событие можно подписаться, чтобы выполнять нужные действия, как только страница завершит все сетевые активности и будет готова для следующей операции.
4. Задержка перед генерацией события.
Задержка в 500 мс добавлена, чтобы устранить "шум" случайных срабатываний и убедиться, что действительно наступило состояние радиомолчания.
📞 Важно:
Модификации роутов в SPA. Если у вашего SPA-приложения не используются сетевые запросы при изменении маршрутов, дополнительно можно привязаться к событиям history.pushState и popstate.
Очистка обсерверов. Не забывайте отключать обсерверы, чтобы избежать утечек памяти, если ваш скрипт прекращает свое действие при определенных условиях.
🫡 Заключение
Этот сниппет помогает организовать логику на основе сетевых событий в инъецируемых скриптах для приложений с динамическим роутингом, позволяя учитывать состояние “радиомолчания” и гарантируя, инъецируемые скрипты выполняются после прогрузки страницы, а также помогает перезапускать инъецируемый скрипт при переходах между страницами.
Ознакомиться со сниппетом можно на GitHub Gist.
А подобные посты чаще в пишу в Telegram канале, там же и пример проекта, где это применимо.