Поделиться через


Хранение данных на устройстве

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

Существует несколько способов, с помощью которых PWA может хранить данные на устройстве, например локальное хранилище, API кэша или IndexedDB.

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

Вариант хранилища Описание
Веб-хранилище Веб-хранилище имеет два типа: сеансовый и локальный. Веб-хранилище полезно для хранения небольших объемов данных из внешнего кода приложения. Данные структурированы как пары "ключ-значение" и доступны только для текущего источника приложения. В случае с хранилищем сеансов данные очищаются по завершении сеанса, например при закрытии приложения или при переходе пользователя к другому источнику в том же окне или на той же вкладке. Локальное хранилище сохраняется до тех пор, пока приложение не удалит данные.
IndexedDB IndexedDB — это API для хранения больших объемов структурированных данных. API является асинхронным и может использоваться как из внешнего кода приложения, так и из кода рабочей роли службы. Используйте API IndexedDB для хранения значительного объема структурированных данных на клиенте или двоичных данных, таких как зашифрованные объекты мультимедиа или файлы.
Кэш API кэша можно использовать для управления кэшируемыми ресурсами. API кэша основан на обещаниях и позволяет разработчикам хранить и извлекать множество веб-ресурсов: HTML, CSS, JavaScript, images, JSON и т. д. Обычно API кэша используется в контексте рабочей роли службы, но он также доступен для внешнего кода приложения.
Доступ к файловой системе API доступа к файловой системе позволяет PWA считывать файлы и папки на устройстве пользователя и сохранять в них изменения.

Примечание. Не используйте WebSQL или кэш приложений. Хотя это два других механизма хранения в браузере, они оба являются устаревшими. Вместо WebSQL используйте IndexedDB. Вместо кэша приложений используйте API кэша.

Веб-хранилище

Веб-хранилище удобно для хранения небольших объемов строковых данных на устройстве пользователя. Простота системы пар "ключ— значение" веб-хранилища делает ее простой в использовании.

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

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

  • sessionStorage Сохраняется только в течение сеанса, например при открытии браузера, в том числе при обновлении страницы.
  • localStorage Сохраняется до тех пор, пока данные не будут удалены кодом приложения, пользователем или браузером.

В следующем коде показано, как использовать localStorage, что аналогично тому, как sessionStorage используется:

const browserInformation = {
  name: 'Microsoft Edge',
  version: 108
};

localStorage.setItem('browser', JSON.stringify(browserInformation));

Приведенный выше код сохраняет объект JavaScript в виде строки JSON в localStorage с помощью setItem() метода и назначает ключ, равный browser. Получить информацию из localStorage можно с помощью метода, getItem() как показано ниже:

const value = localStorage.getItem('browser');

const browserInformation = JSON.parse(value);

Дополнительные сведения см. в разделе API веб-хранилища в MDN.

IndexedDB

IndexedDB — это асинхронный API для хранения структурированных данных, которые можно использовать в интерфейсном коде приложения или коде рабочей роли службы. Используйте API IndexedDB для хранения значительного объема структурированных данных на клиенте или двоичных данных, таких как зашифрованные объекты мультимедиа или файлы.

IndexedDB — лучший вариант для хранения данных в PWA, так как использование API не замедляет работу приложения, блокируя основной поток, и его можно использовать как из интерфейсного кода приложения, так и из рабочей роли службы.

Использование IndexedDB сложнее, чем использование веб-хранилища, и для хранения данных необходимо выполнить следующие действия.

  1. Откройте базу данных с помощью window.indexedDB.open() функции .
  2. Создайте хранилище объектов в базе данных с помощью IDBDatabase.createObjectStore() функции .
  3. Запустите транзакцию для хранения данных с помощью IDBDatabase.transaction() функции .
  4. Дождитесь завершения операции, прослушивая событие.

Дополнительные сведения и примеры кода см. в статье Использование IndexedDB в MDN.

Кэш

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

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

self.addEventListener("fetch", event => {
  async function cacheAndReturnRequest() {
    // Get the response from the server.
    const fetchResponse = await fetch(event.request.url);
    // Open the app's cache.
    const cache = await caches.open("cache-name");
    // Put the response in cache.
    cache.put(event.request.url, fetchResponse.clone());
    // And return the response.
    return fetchResponse.
  }

  event.respondWith(cacheAndReturnRequest());
});

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

Доступ к файловой системе

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

Чтобы открыть файл с устройства пользователя, используйте функцию showOpenFilePicker() :

openFileButton.addEventListener("click", async () => {
  const fileHandles = await window.showOpenFilePicker();
});

Дополнительные сведения см. в разделе Window.showOpenFilePicker() в MDN.

API доступа к файловой системе также можно сочетать с функцией обработки файлов PWA, чтобы зарегистрировать приложение в качестве обработчика файлов определенных типов и, следовательно, чувствовать себя более родной для пользователей. Дополнительные сведения см. в статье Обработка файлов в прогрессивных веб-приложениях.

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

Чтобы открыть файл из исходной файловой системы, используйте navigator.storage API на основе Promise:

// Get the origin-private directory handle.
const root = await navigator.storage.getDirectory();
// Get the handle for a file in the directory.
const fileHandle = await root.getFileHandle("my-file.txt");

Квота хранилища

В Microsoft Edge локальное хранилище и хранилище сеансов ограничено примерно 5 МБ каждый.

Другие типы хранилища данных, такие как IndexedDB, API кэша или API доступа к частной файловой системе источника, могут использовать до 60 % общего дискового пространства на устройстве. Например, если устройство, на котором работает приложение, имеет диск емкостью 64 ГБ, Microsoft Edge позволяет приложению хранить до 38 ГБ данных.

Обратите внимание, что свободное место, доступное на устройстве, может быть меньше 60 % квоты хранилища. Например, если устройство, на котором работает приложение, имеет диск емкостью 64 ГБ, но 50 ГБ уже используется операционной системой и другими файлами, приложение сможет хранить только 14 ГБ данных, даже если квота хранилища по-прежнему составляет 38 ГБ.

С помощью navigator.storage.estimate() можно спросить API диспетчера хранилища, какова квота хранилища для исходного приложения и сколько из нее уже используется. Дополнительные сведения см. в разделе StorageManager.estimate() в MDN.

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

try {
  localStorage.setItem('foo', 'bar');
} catch (e) {
  // Code that handles the lack of storage space.
}

Вытеснение данных

Когда на устройстве пользователя начинается нехватка свободного места на диске, что также называется нехваткой хранилища, Microsoft Edge начнет вытеснить непостоянный объем данных.

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

По умолчанию данные, храняемые приложением, не считаются постоянными и могут быть исключены при нехватке хранилища. Если в приложении хранятся критически важные navigator.storage.persist() данные, используйте функцию , чтобы сделать хранилище приложения постоянным. Постоянное хранилище может быть очищено только пользователем. Дополнительные сведения см. в разделе StorageManager.persist() в MDN.