Мы надеемся, что 2016 год станет годом, когда мы укрепим устойчивость сети.

Интернет-соединения могут быть нестабильными или отсутствовать на ходу, поэтому офлайн-поддержка и надежная работа являются общими характеристиками Progressive Web Apps. В этом посте я обобщу некоторые идеи о автономном хранении данных для PWA - подумайте о полезных нагрузках JSON, изображениях и общих статических данных, необходимых для обеспечения значимого работать в автономном режиме.

Рекомендация по хранению данных в автономном режиме:

Для ресурсов с URL-адресами используйте Cache API (часть Service Worker). Для всех остальных данных используйте IndexedDB (с оболочкой Promises).

Несколько быстрых ответов на распространенные вопросы о том, почему:

  • Оба API являются асинхронными (IDB основан на событиях, а API кэша основан на Promise). Они также работают в Веб-воркерах, оконных и сервисных воркерах.
  • IDB доступен везде. Сервис-воркеры (и Cache API) доступны в Chrome, Firefox, Opera и находятся в разработке для Edge.
  • Хотя IDB не поддерживает Promises, существует несколько сильных библиотек, предоставляющих нам оболочки для Promise. См. рекомендации ниже. API имеет обязательную сложность (транзакции, управление версиями схемы), которую эти библиотеки также пытаются сгладить, где это возможно.
  • Нативная поддержка IDB Promises была предложена, как и наблюдатели.
  • Сколько можно хранить? В Chrome и Opera: ваше хранилище для каждого источника (а не для API). Оба механизма хранения будут хранить данные до тех пор, пока не будет достигнута квота браузера. Приложения могут проверить, сколько квоты они используют, с помощью Quota Management API. Firefox: без ограничений, но отобразит запрос после сохранения 50 МБ данных. Mobile Safari: максимум 50 МБ, Desktop Safari: без ограничений (запросы после 5 МБ), IE10 + максимально до 250 МБ, а запросы - 10 МБ. PouchDB отслеживает поведение хранилища IDB. На будущее: для приложений, требующих более постоянного хранилища, см. Текущую работу над Durable Storage.
  • Safari 10 исправил многие давние ошибки IDB в своих последних технических обзорах. Тем не менее, некоторые люди сталкивались с проблемами стабильности Safari 10 IDB, и PouchDB сочли его немного медленным. Пока здесь не будет проведено больше исследований, YMMV. Пожалуйста, сделайте тест и сообщите об ошибках браузера, чтобы ребята, @webkit и авторы связанных библиотек OSS могли их просмотреть. LocalForage, PouchDB, YDN и Lovefield используют WebSQL в Safari по умолчанию из-за сниффинга UA (в то время не было эффективного способа функционального тестирования на наличие неисправного IDB). Это означает, что эти библиотеки будут работать в Safari 10 без дополнительных усилий (только без прямого использования IDB).
  • Ресурсы с URL-адресом обычно являются статическими ресурсами, которые удивительно ... живут по URL-адресу. Для PWA вы можете кэшировать статические файлы, составляющие оболочку вашего приложения (файлы JS / CSS / HTML) в Cache API, и заполнять данные автономной страницы из IndexedDB. Однако здесь нет жестких правил. Некоторые приложения могут быть достаточно простыми, чтобы использовать только Cache API, в то время как другие могут счесть полезным частичное кэширование своих полезных данных JSON в IDB, чтобы в браузерах без поддержки Cache API вы по-прежнему получали преимущества некоторое локальное кэширование во время сеанса.
  • Поддержка отладки для IndexedDB доступна в Chrome (вкладка Приложение), Opera, Firefox (инспектор хранилища) и Safari (см. Вкладку Хранилище). Отладка IDB в настоящее время не поддерживается в Edge (однако можно отладить базовый JetDB) - проголосуйте здесь за встроенную поддержку.

Стоит попробовать библиотеки IndexedDB

  • LocalForage (~ 8 КБ, обещания, хорошая поддержка устаревших браузеров)
  • Idb-keyval (‹500 байт, обещания, используйте, если нужна только поддержка значения ключа)
  • Idb (~ 1.7KB, Promises, также выполняет итерацию, индексацию)
  • Dexie (~ 16KB, Promises, сложные запросы, вторичные индексы)
  • PouchDB (~ 45KB (поддерживает кастомные сборки), синхронизация)
  • Лавфилд (родственный)
  • LokiJS (в памяти)
  • Ydn-db (dexie-like, работает с WebSQL)

Библиотеки Service Worker, которые стоит проверить

  • Sw-toolbox (автономное кеширование для динамических / динамических запросов)
  • Sw-precache (автономное предварительное кэширование для статических ресурсов / оболочек приложений)
  • Пользователи Webpack могут напрямую использовать вышеуказанный или offline-плагин

А как насчет других механизмов хранения?

  • Веб-хранилище (например, LocalStorage) является синхронным, не имеет поддержки Web Worker и имеет ограниченный размер (только строки). Хотя в прошлом идеи для async LS обсуждались, в настоящее время основное внимание уделяется тому, чтобы IndexedDB 2.0 находился в хорошем состоянии. Я бы лично использовал IDB + библиотеку.
  • Файлы cookie имеют свое применение, но они синхронны, не имеют поддержки Web Worker и имеют ограниченный размер. В предыдущих проектах я использовал js-cookie для обработки файлов cookie через JS (~ 800 байт в сжатом виде). Поддержка Async Cookies API сейчас намечена, а полифилл находится в разработке.
  • WebSQL является асинхронным (на основе обратного вызова), однако он также не имеет поддержки Web Worker и был отклонен Firefox и Edge, но есть в Chrome и Safari.
  • API файловой системы также является асинхронным (на основе обратного вызова) и действительно работает в Web Workers и Windows (хотя и с синхронным API). К сожалению, он не представляет особого интереса за пределами Chrome и изолирован (то есть у вас нет собственного доступа к файлам).
  • File API улучшается в спецификациях File and Directory Entries API и File API. Библиотека File API существует, и для сохранения файлов я использовал FileSaver.js в качестве временного решения. Предложение записываемых файлов может в конечном итоге дать нам лучшее решение, соответствующее стандартам, для беспрепятственного взаимодействия с локальными файлами.

Текущее и будущее автономное хранилище

Если вас интересует автономное хранилище, стоит обратить внимание на следующие усилия. Я особенно рад тому, что поддержка Promises в IndexedDB возможна без библиотеки.

  • Надежное хранилище: защита хранилища от политик очистки пользовательского агента.
  • Indexed Database API 2.0: расширенное управление данными типа "ключ-значение"
  • Promisified IndexedDB: встроенная поддержка дружественной к Promise версии IDB
  • IndexedDB Observers: собственное наблюдение IDB без необходимости использования оболочки вокруг базы данных.
  • Async Cookies API: API асинхронных файлов cookie JavaScript для документов и рабочих
  • Quota Management API: проверьте, сколько квоты использует приложение / источник
  • Файлы с возможностью записи: позволяет сайтам более эффективно взаимодействовать с локальными файлами.
  • Загрузки каталогов: разрешить сайтам загружать каталоги без файлов .zip.
  • File and Directory Entries API: поддержка загрузки файлов и каталогов с помощью перетаскивания

Ресурсы

Автономное хранилище - это не совсем волшебство, и понимание основных API-интерфейсов поможет вам максимально эффективно использовать то, что у нас сейчас есть. Если вы предпочитаете напрямую использовать эти API-интерфейсы или работать с библиотекой абстракций, уделите некоторое время тому, чтобы ознакомиться с вашими вариантами.

Надеюсь, это поможет создать офлайн-интерфейс, который сделает ваш PWA ✨

Выражаем благодарность Нолану Лоусону, Джошуа Беллу (чья работа над Open Web Storage и BlinkOn talk во многом вдохновили эту статью), Джейку Арчибальду, Дрю Ноксу и другим за их предыдущую работу в области веб-хранилища.

Обновите 2 сентября 2016 г., добавив еще несколько часто задаваемых вопросов:

Какие проблемы с выселением существуют для IndexedDB и Cache API? Можно ли сейчас гарантировать, что ответ всегда будет доступен офлайн?

Происхождению дается определенное количество места, с которым можно делать все, что ему заблагорассудится. Это свободное пространство используется всеми формами исходного хранилища (IndexedDB, Cache API, localStorage и т. Д.). Эта сумма не указана и будет варьироваться в зависимости от устройства и условий хранения (например, если устройство уже довольно ограничено).

Когда в веб-хранилище мало (под давлением), UA очищает хранилище, чтобы освободить место. Это может показаться отстойным для автономных приложений, поэтому недавно обновленная спецификация Storage определяет здесь постоянную и максимальную стратегию с максимальным усилием по умолчанию. Максимальное усилие означает, что хранилище можно очистить, не отвлекая пользователя, но означает, что оно менее надежно для долгосрочных или сверхкритичных данных. IndexedDB и Cache API сегодня относятся к категории максимальных усилий.

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

Как узнать, сколько места в хранилище использует мое приложение?

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