КейсыРастИИшка
Приложения для бизнеса

Обновление PWA: новая версия без потери незавершённой работы

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

Обновление PWA разделяет подготовку новой версии, активацию service worker и загрузку нового кода страницы. До перезапуска проверяют незавершённые действия, состояние других вкладок и подтверждение сохранения. Нужны правила миграции черновика и совместимости с сервером. skipWaiting и controllerchange сами по себе не защищают введённые данные.

Новая версия и незавершённая форма
Новая версия и незавершённая форма. Авторская схема 404ai; ситуации учебные.

Новая версия готова. Старая форма ещё не закончена

Учебная ситуация: сотрудник заполняет длинную заявку в установленном PWA. В соседней вкладке открыт список заказов. Команда выкатывает обновление и гордо включает немедленную перезагрузку. Список стал красивее, заявка исчезла, а сотрудник получил практический урок о разнице между успешным релизом и успешной работой пользователя.

Обновление PWA нужно проектировать как переход между состояниями приложения. В момент релиза человек может вводить данные, ждать ответ сервера или держать вторую вкладку со старым кодом. Сам факт появления нового service worker не подтверждает, что текущую работу можно прервать. Нужны условия активации, сохранения и продолжения.

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

Три разных события, которые интерфейс называет обновлением

Первое событие: новая версия обнаружена и подготовлена. Второе: новый service worker стал активным. Третье: страница загрузила новый код и готова работать с ним. Это не одна операция. Если интерфейс сообщает «обновлено» на первом шаге, пользователь может продолжать видеть старое приложение. Если автоматически перезагружает на втором — потерять незавершённое состояние.

В разборе жизненного цикла service worker на web.dev описано ожидание новой версии, пока прежняя контролирует клиентов. Это механизм согласования, а не поломка установки.

Service worker и уже загруженный JavaScript страницы тоже не следует считать одним объектом. Смена управляющего worker не переписывает автоматически весь код открытой вкладки. Поэтому проект должен учитывать сочетания версий, которые действительно возникают при переходе. Иначе обновлённая инфраструктура начинает обслуживать страницу, чьи предположения остались прежними.

Пользователю обычно не нужны эти технические термины. Ему нужно спокойное сообщение: новая версия доступна, что нужно сохранить и когда можно продолжить. Но команда обязана различать состояния внутри системы. Хорошее простое объяснение получается из точной модели, а не из одной кнопки, которая делает сразу всё.

Три события вместо одной кнопки
Три события вместо одной кнопки. Авторская схема 404ai; ситуации учебные.

Одна вкладка не может отвечать за все остальные

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

Для начала достаточно определить, какие состояния считаются занятыми. Изменённая форма, отправляемый запрос, подготовленный, но не подтверждённый документ. У каждого свой способ безопасного завершения. Слово «пользователь активен» слишком расплывчато: человек может уйти от компьютера с важными данными, а может активно читать страницу без каких-либо изменений.

Вкладкам нужен согласованный способ сообщать о готовности. Как именно он реализован, зависит от архитектуры. Важно различать разрешение на смену версии и подтверждение, что данные действительно сохранены. Простого сообщения «можно обновляться» недостаточно, если запись черновика завершилась ошибкой. Для принятия решения нужна проверяемая последовательность.

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

Почему skipWaiting не является кнопкой сохранения

MDN описывает skipWaiting() как перевод ожидающего service worker к активации. Метод не сохраняет форму и не проверяет готовность открытых страниц.

Использовать его можно в осмысленном сценарии. Например, приложение подготовило совместимую версию, предупредило человека и подтвердило сохранение черновика. Тогда принудительное завершение ожидания является одним техническим шагом. Если вызвать метод без модели незавершённой работы, он просто быстрее доведёт пользователя до неожиданного перехода.

Не всякое обновление должно ждать ручной кнопки. Часть изменений допускает фоновый переход без перезагрузки текущей страницы. Другая требует смены интерфейса. Для критического исправления может понадобиться отдельная обязательная политика. Но даже она должна объяснять, что произойдёт с данными, и иметь предусмотренный способ завершения работы. Срочность не делает состояние формы менее реальным.

Полезно классифицировать релиз по его влиянию: совместимая смена служебного кода, обновление интерфейса, изменение формата локальных данных, прекращение поддержки старого клиента. Для каждой категории определяют условия перехода. Такая классификация позволяет не заставлять людей перезапускать приложение ради изменения, которое не требует этого действия.

Черновик — отдельный результат, а не содержимое памяти

Если текст существует только в состоянии открытой страницы, перезагрузка его не сохранит. Чтобы обещать продолжение, приложению нужен явный механизм черновика. Он должен понимать, что сохранено, где и к какой версии формы относится. Надпись «данные сохраняются» без подтверждения создаёт более опасное ожидание, чем честное предупреждение о необходимости закончить работу.

Для учебной заявки достаточно версии формата, времени записи и известного состояния. Какие поля обязательны для восстановления? Можно ли оставить часть незаполненной? Что делать с уже выбранной позицией, если она изменилась? Эти вопросы лучше решить до релиза. Универсальное сохранение сериализованного объекта не гарантирует, что новая форма правильно поймёт его смысл.

Сохранение черновика и отправка заявки — разные действия. Пользователь может сохранить промежуточный вариант и ещё не хотеть передавать его компании. Обновление не должно превращать черновик в отправленное обращение. Техническое удобство миграции не даёт приложению право завершить решение за человека. После восстановления статус должен оставаться понятным.

При ошибке сохранения нужен рабочий выход: повторить, дать возможность скопировать ввод или отложить переход в предусмотренных пределах. Конкретная альтернатива зависит от данных. Важно, чтобы окно обновления не перекрывало форму навсегда и не предлагало единственную кнопку, которая уничтожит работу. Ошибка — часть сценария, а не отдельный случай для поддержки после запуска.

Две вкладки должны пережить переход
Две вкладки должны пережить переход. Авторская схема 404ai; ситуации учебные.

Две версии формы и один формат данных

Предположим, новая заявка разделила поле «адрес» на несколько частей. Старый черновик содержит одну строку. Автоматически разнести её по новым полям без проверки может быть невозможно. Нужна политика миграции: сохранить исходную строку, показать человеку требуемое уточнение и не выдавать предположение за подтверждённый адрес. Это учебный пример, не рекомендация конкретной схемы хранения.

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

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

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

Сервер тоже участвует в переходе

Даже если все новые страницы уже готовы, старая вкладка может некоторое время обращаться к серверу прежним способом. Поэтому релиз должен учитывать совместимость клиента и API. Важно знать, какие запросы ещё приходят, какие поля обязательны и как сервер сообщает о неподдерживаемом формате. Молчаливое игнорирование данных хуже явного объяснения.

Для незавершённой формы особенно неприятен сценарий, когда заполнить её ещё можно, а отправить уже нельзя. Если прекращение поддержки необходимо, пользователь должен получить понятный путь сохранения и перехода до потери работы. Просто заменить техническую ошибку на фразу «обновите страницу» недостаточно. Нужно объяснить судьбу введённых сведений.

Клиентский и серверный релизы необязательно происходят одновременно. Это нормальное условие веб-приложения. Для приёмки полезно явно проверить сочетания: старый клиент с новым сервером и новый клиент с действующим сервером переходного периода. Если одно сочетание недопустимо, должен существовать управляемый запрет, а не случайный сбой посреди действия.

Эта задача относится к разработке приложений для бизнеса, когда приложение участвует в рабочем процессе. Стоимость обновления определяется не только количеством экранов. Длительность открытой работы, ценность черновиков и устройство обмена часто влияют на сложность сильнее очередной анимации кнопки установки.

Матрица версий и черновика
Матрица версий и черновика. Авторская схема 404ai; ситуации учебные.

Матрица, которую стоит пройти перед выпуском

Ниже — заготовка приёмки программного обновления. Она не подтверждает одинаковое поведение всех браузеров. Поддерживаемые платформы, версии и способы запуска нужно определить для проекта и проверить отдельно. Особенно важно не ограничиваться одной вкладкой разработчика с пустой формой.

Сочетание Ожидаемый результат
Одна вкладка, изменений нет Понятный переход к новой версии
Форма изменена Работа сохранена или переход отложен по правилу
Две вкладки, одна занята Состояние занятой не игнорируется
Ошибка сохранения Нет ложного подтверждения безопасности перезапуска
Старый черновик, новая форма Применена проверенная миграция или объяснено уточнение
Новый сервер, старый клиент Совместимый обмен или управляемое завершение
Откат после миграции Нет молчаливой порчи локальных данных

Для каждого испытания сохраняют версию клиента, worker, сервера и формата данных. Это не набор терминов ради сложности. Без них запись «обновление не сработало» не позволяет восстановить сочетание, на котором возникла ошибка. Поддержке приходится гадать по внешнему виду интерфейса и памяти пользователя.

Повторите сценарий с открытой вкладкой, которая не была активной во время релиза. Затем вернитесь к ней и попробуйте продолжить работу. Этот простой тест показывает, была ли политика рассчитана на реальные рабочие привычки. Вторая вкладка не обязана вовремя прочитать сообщение, которое команда показала только в первой.

Сообщение об обновлении должно описывать действие

«Доступна новая версия» — полезная информация, но недостаточная инструкция. Человек должен понять, можно ли обновить сейчас и что произойдёт с текущим вводом. Например, приложение сообщает, что черновик сохранён, и предлагает перезапуск. Либо предупреждает, что сначала нужно завершить определённое действие. Формулировка должна соответствовать реальному состоянию.

Не стоит показывать успешное сохранение раньше завершения операции. Иначе человек нажмёт обновление в момент, когда данные ещё находятся в пути. Если проверка заняла время, интерфейс сообщает о процессе и удерживает опасное действие до результата. Это небольшая задержка, у которой есть понятная функция: защита незавершённой работы.

Нужен и сценарий отказа. Пользователь решил продолжить текущую задачу. Приложение должно объяснить, сколько это допустимо и когда снова предложит переход, если такие пределы предусмотрены. Бесконечно всплывающее окно не делает обновление безопаснее. Оно просто учит быстрее нажимать первую заметную кнопку.

В описании controllerchange на MDN событие связано со сменой активного worker. Это сигнал для логики приложения, а не самостоятельное разрешение безусловно перезагрузить заполненную страницу.

Что не исправляется одной очисткой кэша

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

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

Отдельно существует офлайн-режим и синхронизация. Обновление не должно объявлять такую очередь пустой или отправленной без проверки, но устройство всей очереди не следует прятать в инструкцию перезапуска. У каждой системы данных нужны собственные состояния и правила приёмки. Смешение тем обычно заканчивается одной кнопкой «начать заново».

Для поддержки полезен безопасный диагностический пакет: известные версии, состояние перехода, подтверждение наличия черновика и описание ошибки. Его состав определяется с учётом данных проекта. Нельзя автоматически выгружать содержимое форм в технический журнал только ради удобства поиска проблемы. Часто для воспроизведения достаточно структуры состояния и допустимого тестового примера.

Что значит безопасно обновиться
Что значит безопасно обновиться. Авторская схема 404ai; ситуации учебные.

Экономика обновления, которое не заставляет переделывать

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

Стоимость зависит от продолжительности работы в форме, числа поддерживаемых платформ и необходимости миграций. Короткий публичный просмотр и рабочая заявка с десятками полей требуют разных решений. Поэтому обсуждение обновления должно начинаться на этапе проектирования сценария, а не после первого сообщения «после релиза всё пропало».

Для небольшого приложения разумно выбрать ограниченный, понятный механизм: обнаружить новую версию, показать состояние, сохранить нужный черновик, согласовать переход и восстановить работу. Необязательно сразу строить сложный центр управления версиями. Но исключения — вторая вкладка, ошибка сохранения, неизвестный формат — должны иметь предусмотренный выход.

Результат приёмки формулируется действиями. Новая версия обнаруживается. Занятая вкладка не игнорируется. Неудачное сохранение не получает зелёный статус. Черновик читается новой формой либо человек видит, что уточнить. Старый клиент не теряет данные при общении с переходным сервером. Эти признаки полезнее общей фразы «обновляется автоматически».

Один обязательный вопрос перед каждым релизом

Спросите команду: что произойдёт с человеком, который начал работу до выпуска и продолжит её после? Если ответ сводится к «обновит страницу», сценарий пока не описан. Нужно пройти судьбу введённых данных, версию формы, состояние других вкладок и совместимость обмена. Именно там живёт обновление рабочего приложения.

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

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

Источники и границы разбора

Проверено 3 ноября 2026. Документы платформ подтверждают отдельные механизмы и определения. Предлагаемые маршруты и условные примеры — авторская методика, а не отчёт о внедрении или обещание клиентов.

  1. web.dev — The service worker lifecycle

    Открыт разбор waiting/activation. Не подтверждает сохранение формы и одинаковое поведение конкретного приложения на всех платформах.

  2. MDN — ServiceWorkerGlobalScope.skipWaiting

    Открыто описание активации ожидающего worker. Метод не является механизмом сохранения пользовательского ввода.

  3. MDN — controllerchange event

    Открыта документация события смены worker. Событие само не разрешает безусловную перезагрузку страницы с незавершённой работой.

Частые вопросы

Почему новый service worker остаётся в waiting?

Новая версия может ожидать, пока прежний service worker контролирует открытые клиенты. Это часть жизненного цикла, а не обязательно ошибка установки. Для рабочего приложения нужно определить, когда переход допустим и как учесть незавершённые действия. Одна свободная вкладка не подтверждает готовность другой, где человек ещё заполняет форму или ждёт результат операции.

Достаточно вызвать skipWaiting для безопасного обновления?

Нет. Метод ускоряет переход ожидающего worker к активации, но не сохраняет форму и не принимает решение за пользователя. До него проект проверяет нужные состояния и совместимость. Отдельно определяется загрузка нового кода страницы. Автоматическая перезагрузка без подтверждённого сохранения способна потерять ввод даже при технически успешной активации новой версии приложения.

Что проверять при двух открытых вкладках?

Нужно знать, есть ли в каждой незавершённая работа и подтверждено ли её сохранение. Вкладки должны согласованно участвовать в переходе; молчание одной не становится автоматическим согласием. Проверьте возвращение к неактивной вкладке после релиза, закрытие и ошибку сохранения. Конкретный механизм и поддерживаемые платформы выбираются и испытываются для проекта отдельно.

Как сохранить старый черновик в новой форме?

Определите версию формата и правила чтения, преобразования и уточнения полей. Новая форма может не понимать старое состояние автоматически. Проверяйте полный, частичный и неизвестный вариант, а также последствия отката. Черновик остаётся черновиком: обновление не должно незаметно отправлять его как заявку или объявлять недостающие сведения подтверждёнными данными пользователя.

Это то же самое, что очистить HTTP-кэш?

Нет. Загрузка ресурсов и переход незавершённой работы — связанные, но разные задачи. Правильные заголовки не сохраняют форму. Очистка локальных данных может уничтожить нужное состояние. Сначала устанавливают, что хранится и где есть подтверждённая копия. Затем проверяют worker, страницу, черновик и сервер, вместо универсального совета начать всё заново после очистки.

Разобрать задачу вашей компании

Приложения для бизнеса: возможности, примеры и условия.

Обсудить свою задачу
Разбор задачи — бесплатноОтвет за 15 минут
Разобрать задачу