Как вести себя приложению при медленном интернете
Что проверяют
Думаете ли вы о пользователе на плохой сети или только о своём быстром офисном Wi-Fi. Хороший ответ разделяет медленную первую загрузку, медленные запросы во время работы и полное отсутствие связи. Следом часто спрашивают, как вы это тестируете.
Как отвечать
Три сценария, у каждого свои меры:
- первая загрузка: сократить критический путь. Разбиение кода по роутам через динамический
import(),deferдля скриптов, сжатие Brotli, хешированные имена файлов сCache-Control: max-age=31536000, immutable, изображения в AVIF или WebP сsrcsetиloading="lazy"ниже первого экрана,font-display: swap. SSR или потоковый рендер показывают контент раньше, чем догрузится JavaScript; - медленные запросы: скелетоны там, где понятна форма контента, спиннер с задержкой около 300 мс, чтобы он не мигал на быстрых ответах. Таймаут через
AbortSignal.timeout(), отмена устаревших запросов черезAbortController(иначе в поиске старый ответ перетрёт новый), повторы с экспоненциальной задержкой только для идемпотентных запросов. TanStack Query или SWR дают кэш с фоновым обновлением: пользователь видит прошлые данные, пока грузятся новые. Плюс оптимистичные обновления с откатом при ошибке; - нет связи: события
online/offline, Service Worker (часто через Workbox) для офлайн-оболочки и очереди отправок.
Можно упомянуть navigator.connection.effectiveType и saveData для облегчённого режима, но этот API есть только в Chromium-браузерах, Safari и Firefox его не поддерживают.
Проверяют всё это в DevTools с профилями троттлинга сети, а в проде смотрят реальные LCP и INP по сегментам пользователей.
Где спотыкаются
Перечисляют только оптимизацию бандла и забывают про запросы. У fetch нет своего таймаута, и кнопка «Сохранить» может висеть минутами без обратной связи.
Повторяют любые запросы подряд, включая POST. На плохой сети это дубли заказов и лишняя нагрузка на сервер, который и так не отвечает.
Верят navigator.onLine. Значение true означает только подключение к какой-то сети, а не доступ к интернету, поэтому реальную доступность проверяют по ответам сервера.