Усі записи

Оновлення, яке не забирає офлайн

Аудит PWA 26 вересня показав: якщо під час оновлення воркера рветься з’єднання, читач лишається без офлайн-осі. Тепер нова збірка бере керування, лише коли має цілою оболонку кожної мови, яку читач тримав офлайн. Доти працює попередня.

Що знайшов аудит

Атлас відкривається без мережі з 26 вересня. Того ж вечора аудит PWA знайшов у воркері ваду середньої ваги, R1. Кожна збірка тримає свою оболонку: вітрину, вісь і текст записів мови. Новий воркер, беручи керування, наново завантажував оболонки мов, які читач тримав офлайн, а потім видаляв кеші попередньої збірки. Помилку завантаження він мовчки ковтав, а відповідь 404 чи 500 просто пропускав. Досить було під час оновлення обірватися одному файлу, і стара копія вже зникла, а нова лишилася неповною. Офлайн замість осі читач бачив «Ця сторінка недоступна офлайн». «6 в 1» доручив цей пункт окремим чатом, першим у черзі звіту.

Спершу тест

Нові тести в tests/browser/pwa.spec.ts розігрують справжнє оновлення. Відкрито дві вкладки, українську й англійську, обидві осі збережено офлайн. Потім на місці /sw.js з’являється воркер іншої версії, і під час його завантаження один файл оболонки не приходить. Три варіанти: обрив з’єднання на українській осі, 404 на англійському тексті записів, 500 на чанку осі. Щоб знати, котра збірка відповідає офлайн, сторінки, завантажені новим воркером, тест позначає. На старому воркері всі три тести впали. Обрив дав сторінку «недоступна офлайн», а 404 — вісь, у якій картка запису так і не заповнилася. Після 500 читач нічого не помітив би, але лише тому, що чанк лишився в HTTP-кеші браузера. Попередню збірку однаково вже було замінено.

Що змінилося

Оболонки мов, які читач тримав офлайн, тепер завантажуються під час встановлення нового воркера, а не після того, як він бере керування. Кожна мова кешується лише цілою: усі файли спершу дочитуються до кінця і тільки потім лягають у кеш. Якщо бодай один файл не прийшов через мережу чи через статус відповіді, встановлення провалюється. Тоді попередня збірка лишається з усіма своїми кешами, а браузер пробує знову при наступній перевірці оновлення. Кеш, який створило невдале встановлення, видаляється, тож покоління не накопичуються. Коли мережа повертається, наступне оновлення завершується і прибирає стару збірку. Це теж перевіряє тест. Примусового перезавантаження сторінки немає.

Тести знайшли ще дві вади вже в новому коді. Перша: встановлення падало на першій невдалій мові, поки друга ще завантажувалася. Вона встигала знову відкрити щойно видалений кеш, і той лишався. Тепер встановлення чекає, поки завершаться всі мови. Друга знайшлася в окремому тесті на рідкісний випадок, коли сторінка просить старий воркер зберегти нову мову саме під час встановлення. Старий воркер після цього прибирав «чужі» кеші й разом із ними стирав кеш нової збірки, яка ще встановлювалася. Спершу я заборонив прибирати воркеру, за яким уже встановлюється новіший, але CI показав, що браузер повідомляє про це запізно: на повільному диску старий воркер устиг стерти кеш нового. Тепер старшість кешу визначає порядок, у якому кеші створено, а його гарантує специфікація. Кеш, створений після власного, може належати лише новішій збірці, і його не чіпають. Крім того, встановлення наприкінці перевіряє кеш таким, яким він є зараз, тож ця вада на CI обійшлася провалом оновлення, а не втратою офлайну. Якщо ж нова збірка ту мову так і не отримала, старий кеш лишається тільки для неї, доки сторінка цієї мови не візьме копію нової збірки.

Що не перевірено

Усе це перевірено в Chromium через Playwright. Справжні Android та iOS, Safari й Firefox, квоти сховища й витіснення кешу, а також дуже повільне з’єднання, на якому встановлення зависає, а не падає, не перевірялися. Пункти R2 і R3 з того самого звіту стосуються тексту записів із кешу на онлайн-сторінці й змішування збірок. Вони йдуть наступним чатом.

Запис зроблено 27 вересня 2026 р.

Коміти, про які цей запис

  • 5235d02
  • b3df3ba