Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Офлайн-режим веб-приложения

Офлайн-режим: работа без соединения и очередь изменений

Автономная работа приложения: кэш ресурсов, локальное хранение изменений, очередь отправки и разрешение конфликтов при возврате сети.

Прямой ответ

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

Компонент Что обеспечивает
Кэш ресурсов Загрузку оболочки без сети
Локальное хранилище Сохранение изменений до отправки
Очередь отправки Порядок применения изменений
Разрешение конфликтов Обработку расхождений при возврате сети
// сохранение изменения без сети
await db.put("drafts", { id, body, updatedAt: Date.now() });
queue.enqueue({ id, body });   // отправка при появлении сети

Изменение сохраняется локально и ставится в очередь, поэтому действие не теряется при отсутствии соединения. О кэше — в статье про service worker.

Кэш оболочки и открытие без сети

Кэш оболочки обеспечивает загрузку интерфейса без соединения, поэтому приложение открывается и показывает прежнее содержимое.

Оболочка приложения. Разметка, стили и код помещаются в кэш при установке, поэтому загрузка не требует сети.

Прежнее содержимое. Данные из кэша отображаются как последнее известное состояние, поэтому пользователь видит содержимое до обновления.

Страница без соединения. Запрос, не найденный в кэше, отдаёт страницу с сообщением об отсутствии сети вместо ошибки.

Практическое следствие: приложение без кэша оболочки не открывается без соединения, поэтому автономный режим невозможен независимо от сохранённых данных.

Отдельный аспект — указание на устаревание. Содержимое из кэша сопровождается признаком давности, поэтому пользователь определяет, что значение может отличаться от актуального.

Локальное хранение изменений

Изменения сохраняются в локальном хранилище до отправки, поэтому действие пользователя не теряется при отсутствии соединения.

Сохранение изменения. Значение записывается в хранилище с отметкой времени, поэтому изменение доступно после перезапуска приложения.

Объём хранилища. Локальное хранилище ограничено по объёму, поэтому состав сохраняемых данных выбирается по необходимости.

Идентификатор изменения. Каждое изменение сопровождается идентификатором, поэтому повторная отправка одного изменения не создаёт дубль.

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

Очередь отправки и разрешение конфликтов

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

Порядок отправки. Изменения отправляются в порядке постановки, поэтому последовательность действий сохраняется.

Повтор при отказе. Изменение, отклонённое при отправке, остаётся в очереди, поэтому отправка повторяется без потери.

Разрешение конфликта. Значение, изменённое на сервере после сохранения локально, требует правила выбора, поэтому расхождение разрешается явно.

Практическое следствие: отправка изменений без порядка может применить более раннее изменение после более позднего, поэтому итоговое значение не соответствует последнему действию.

Об установке приложения — в статье про PWA; о стратегиях кэша — в статье про кэширование в браузере.

Практика: настройка автономного режима

1. Помещайте оболочку приложения в кэш при установке. Загрузка интерфейса не требует соединения.

2. Показывайте прежнее содержимое с признаком давности. Пользователь определяет, что значение может отличаться от актуального.

3. Отдавайте страницу без соединения вместо ошибки. Отсутствие сети объявляется явно, поэтому состояние приложения понятно.

4. Сохраняйте изменения локально с отметкой времени. Действие не теряется при перезагрузке страницы без сети.

5. Ставьте изменения в очередь с идентификатором. Повторная отправка не создаёт дубль, поэтому изменение применяется один раз.

6. Отправляйте изменения в порядке постановки. Последовательность действий сохраняется, поэтому итоговое значение корректно.

7. Задайте правило разрешения конфликтов. Расхождение с данными на сервере разрешается явно, а не произвольно.

Рекомендации:

  1. Не рассчитывайте на неограниченный объём локального хранилища. Состав сохраняемых данных выбирается по необходимости.
  2. Учитывайте устаревание кэшированного содержимого. Значение из кэша требует признака давности.
  3. Сопоставляйте правило разрешения конфликта с назначением данных. Последнее изменение и значение на сервере дают разный результат.
  4. Фиксируйте проверку автономной работы в процессе разработки. Отсутствие кэша оболочки обнаруживается до выпуска.
  5. Пересматриваем состав кэша при изменении оболочки. Новый ресурс требует включения в предварительный кэш.

Практический сценарий: изменения терялись при потере соединения

Контекст: пользователь заполнял форму в поезде, соединение прерывалось, и введённые значения исчезали после перезагрузки страницы.

  1. Диагностика. Проверка показала, что изменение отправлялось на сервер непосредственно при вводе без локального сохранения. При отсутствии соединения запрос завершался отказом, а значение не сохранялось, поэтому перезагрузка страницы теряла ввод.
  2. Причина. Отсутствие локального хранения и очереди отправки приводило к тому, что изменение существовало только в памяти страницы.
  3. Действия. (а) Добавили сохранение изменения в локальное хранилище с отметкой времени, чтобы значение сохранялось до отправки; (б) реализовали очередь отправки с идентификатором изменения, чтобы повторная отправка не создавала дубль; (в) обеспечили отправку в порядке постановки, чтобы последовательность действий сохранялась; (г) задали правило разрешения конфликта при расхождении с данными на сервере; (д) поместили оболочку приложения в кэш, чтобы страница открывалась без соединения.
  4. Результат. Введённые значения сохраняются при потере соединения и отправляются после восстановления сети, поэтому действие пользователя не теряется.

Вывод: отправка изменения непосредственно на сервер без локального сохранения приводит к потере ввода при отсутствии соединения. Локальное хранилище с очередью отправки и кэш оболочки обеспечивают сохранение действия и его применение после восстановления сети.

FAQ

Что нужно для работы приложения без соединения? Кэш оболочки приложения и локальное хранение изменений. Без кэша оболочка не загружается, без хранилища действие теряется.

Зачем помещать изменение в очередь отправки? Отправка выполняется в порядке постановки после восстановления сети, поэтому последовательность действий сохраняется.

Как избежать дублей при повторной отправке? Идентификатором изменения. Повторная отправка одного идентификатора не создаёт новую запись.

Что делать при расхождении локального значения с данными на сервере? Применять заданное правило разрешения конфликта. Выбор значения выполняется явно, а не произвольно.

Источники: W3C Service Workers, MDN IndexedDB, web.dev Offline Cookbook — ссылки в шапке.