Один из самых частых вопросов, которые нам задают в Progressier, касается кэширования на стороне клиента. Как убедиться, что PWA всегда отображает актуальные данные и активы, а также эффективно использует кэширование?

Хотя PWA часто выглядит и воспринимается как нативное приложение, с технической точки зрения оно действительно работает как любой другой веб-сайт. Когда вы открываете страницу, она загружает активы (изображения, скрипты, таблицы стилей…) и данные (пользовательские данные, данные о продукте…). Эти ресурсы извлекаются из сети, а затем используются браузером.

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

Трюк с версиями

Управление версиями, вероятно, самый простой способ заставить браузер загрузить ресурс с вашего сервера. Когда вы обновляете ресурс, добавьте параметр к URL-адресу ресурса, где бы вы ни запрашивали код. Например, измените код на стороне клиента на requestdomain.com/data.json?version=2 вместо domain.com/data.json?version=1.

Браузер увидит эти два URL-адреса и посчитает их совершенно разными активами. Таким образом, он не будет использовать кешированную версию первого, когда страница явно запрашивает второе. Хорошей практикой является добавление номера версии (или любой другой строки запроса) к ключевым ресурсам в процессе сборки, чтобы вам не приходилось делать это вручную каждый раз, когда вы вносите изменения.

Заголовок Cache-Control

Когда сервер успешно отвечает на HTTP-запрос, он возвращает сам актив (файл JavaScript, изображение, файл CSV…), но также отправляет заголовки — параметры, которые сообщают браузеру, что им разрешено или не разрешено делать с ресурс.

Одним из таких заголовков является заголовок Cache-Control. Он существует специально для того, чтобы вы могли указать браузеру, как тот или иной ресурс должен кэшироваться (или нет) и перепроверяться (или нет).

Если вы управляете сервером, который отвечает на запрос, вы можете установить разные Cache-Controlheaders и указать браузеру, как он должен обрабатывать каждый конкретный ресурс. Например, установите для заголовка Cache-Control значение no-cache, чтобы вообще запретить браузеру кэшировать ресурс.

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

Первая сетевая стратегия

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

Существует еще один механизм кэширования, который называется Cache API. И это доступно в сервисных работниках. Progressier использует этот API для создания стратегии кэширования. Вы можете определить очень конкретные правила для каждого типа ресурсов, не написав ни одной строки кода.

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

Конечно, в большинстве случаев вы захотите быть более конкретным и применить эту стратегию к ресурсам, которые являются критически важными, и использовать более удобные для кэширования стратегии для менее важных ресурсов (например, Stale-While-Revalidat).

Поддельная кнопка перезагрузки

С помощью первых трех методов вы, по сути, сообщаете браузеру, следует ли извлекать конкретный ресурс из кеша или из сети при загрузке страницы.

Но после установки открытие PWA не всегда может вызвать перезагрузку новой страницы. Вы можете запустить PWA с домашнего экрана, сделать с ним все, что вам нужно, затем запустить другое приложение и вернуться к PWA на следующий день.

Если вы тем временем не закрыли приложение или не выключили телефон, страница не будет перезагружаться — вместо этого она просто позволит вам продолжить сеанс с того места, где вы остановились. Если вы, владелец приложения, тем временем обновили ресурсы, пользователь может по-прежнему использовать устаревшие ресурсы. Как вы можете заставить PWA обновлять свой контент?

Когда мы запустили приложение Коронавирус в январе 2020 года, пользователи очень требовательно относились к актуальности данных. Мы автоматически обновляли данные каждые 15 минут, поэтому было крайне важно, чтобы пользователи не видели устаревшие данные (иначе мы получили бы тонны гневных писем!).

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

Создавать иллюзию того, что что-то происходит, — мощная концепция UX. В нашем случае цель была двоякой: сделать так, чтобы приложение постоянно обновлялось (как оно и было на самом деле — просто не синхронно с фальшивой кнопкой перезагрузки) и не показывать устаревшие данные.

Заключение

Так вот. Три разных метода кэширования, чтобы ваше PWA постоянно обновлялось, и один маленький трюк UX.

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

И если это невозможно легко реализовать в процессе сборки, вы можете либо использовать заголовок Cache-Control (для ресурсов, которыми вы владеете), либо метод Service Worker для детального определения поведения кэширования.

Что вы думаете? Используете ли вы другие методы для обновления PWA?

Больше контента на plainenglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку здесь.