Almacenamiento de datos en el dispositivo

La Web Apps progresiva (PWA) ofrece opciones sólidas para almacenar datos localmente para permitir a los usuarios seguir trabajando incluso si la conexión de red se vuelve inestable o se desconecta.

Hay varias maneras en las que un PWA puede almacenar datos en un dispositivo, como el almacenamiento local, la API de caché o IndexedDB.

En la tabla siguiente se describen las distintas opciones y el resto de este artículo incluye más detalles y escenarios de uso para cada opción.

Opción de almacenamiento Descripción
Almacenamiento web Web Storage tiene dos tipos: sesión y local. El almacenamiento web es útil para almacenar pequeñas cantidades de datos del código front-end de la aplicación. Los datos se estructuran como pares clave-valor y solo están disponibles para el origen de la aplicación actual. En el caso del almacenamiento de sesión, los datos se borran cuando finaliza la sesión, por ejemplo, cuando se cierra la aplicación o cuando el usuario busca otro origen en la misma ventana o pestaña. El almacenamiento local persiste hasta que la aplicación quita los datos.
IndexadoDB IndexedDB es una API para almacenar grandes cantidades de datos estructurados. La API es asincrónica y se puede usar tanto desde el código front-end de la aplicación como desde el código de trabajo del servicio. Use indexedDB API para almacenar una cantidad significativa de datos estructurados en el cliente, o datos binarios, como archivos o objetos multimedia cifrados.
Caché La API de caché se puede usar para administrar los recursos almacenados en caché. Cache API se basa en Promise y permite a los desarrolladores almacenar y recuperar muchos recursos web: HTML, CSS, JavaScript, imágenes, JSON, etc. Normalmente, la API de caché se usa en el contexto de un trabajo de servicio, pero también está disponible para el código front-end de la aplicación.
Acceso al sistema de archivos La API de acceso del sistema de archivos permite a la PWA leer archivos y carpetas en el dispositivo del usuario y guardar los cambios en ellos.

Nota: No use WebSQL ni La caché de aplicaciones. Aunque estos son otros dos mecanismos de almacenamiento del explorador, ambos han quedado en desuso. En lugar de WebSQL, use IndexedDB. En lugar de caché de aplicaciones, use la API de caché.

Almacenamiento web

El almacenamiento web es útil para almacenar pequeñas cantidades de datos de cadena en el dispositivo del usuario. La simplicidad del sistema de par clave-valor de Web Storage facilita su uso.

Web Storage funciona sincrónicamente solo en el subproceso principal de la aplicación. Esto significa que El almacenamiento web no está disponible para su uso dentro de los trabajadores del servicio y que el uso intensivo de Web Storage puede crear problemas de rendimiento para la aplicación.

Cada tipo de almacenamiento web, de sesión y local, se mantiene como un almacén de datos independiente que está aislado en el dominio que lo creó.

  • sessionStorage solo se conserva durante la sesión, por ejemplo, mientras el explorador está abierto, lo que incluye cuándo se actualiza la página.
  • localStorage se conserva hasta que el código de la aplicación, el usuario o el explorador quitan los datos.

En el código siguiente se muestra cómo usar localStorage, que es similar a cómo sessionStorage se usa:

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

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

El código anterior almacena un objeto JavaScript como una cadena JSON en localStorage mediante el setItem() método y asigna una clave igual a browser. Puede recuperar la información de localStorage mediante el getItem() método como se muestra a continuación:

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

const browserInformation = JSON.parse(value);

Para más información, consulte Api de almacenamiento web en MDN.

IndexadoDB

IndexedDB es una API asincrónica para almacenar datos estructurados que se pueden usar en el código front-end o el código de trabajo de servicio de la aplicación. Use indexedDB API para almacenar una cantidad significativa de datos estructurados en el cliente o datos binarios, como archivos o objetos multimedia cifrados.

IndexedDB es la mejor opción para almacenar datos en la PWA, ya que el uso de la API no ralentiza la aplicación bloqueando el subproceso principal y se puede usar tanto desde el código front-end de la aplicación como desde el trabajo de servicio.

El uso de IndexedDB es más complejo que el uso de Web Storage y requiere los pasos siguientes para almacenar datos:

  1. Abra una base de datos mediante la window.indexedDB.open() función .
  2. Cree un almacén de objetos en la base de datos mediante la IDBDatabase.createObjectStore() función .
  3. Inicie una transacción para almacenar datos mediante la IDBDatabase.transaction() función .
  4. Espere a que se complete la operación, escuchando un evento.

Para obtener más información y ver ejemplos de código, consulte Uso de IndexedDB en MDN.

Caché

Cache API es un sistema para almacenar y recuperar solicitudes y respuestas de red en el código front-end o el trabajo de servicio de la aplicación. Se puede usar para almacenar recursos, como imágenes y archivos, localmente en el dispositivo del usuario. Esto puede hacer que la aplicación funcione incluso cuando está sin conexión o mejorar su rendimiento al reducir el número de solicitudes de red necesarias para representar la aplicación.

El siguiente fragmento de código muestra cómo escuchar el fetch evento en un trabajo de servicio y almacenar la respuesta desde el servidor mediante la API de caché:

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());
});

Para detectar otros escenarios útiles de Cache API, consulte Uso de service workers para administrar solicitudes de red.

Acceso al sistema de archivos

La API de acceso al sistema de archivos permite que la aplicación acceda a los archivos del dispositivo del usuario de forma similar a las aplicaciones nativas. Se puede usar para crear aplicaciones que puedan leer y escribir archivos, como editores de texto o imágenes.

Para abrir un archivo desde el dispositivo del usuario, use la showOpenFilePicker() función :

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

Para obtener más información, vea Window.showOpenFilePicker() en MDN.

La API de acceso al sistema de archivos también se puede combinar con la característica de control de archivos PWA para registrar la aplicación como un controlador de tipos de archivo específicos y, por tanto, se siente más nativa para los usuarios. Para obtener más información, consulte Control de archivos en Web Apps progresiva.

La API de acceso del sistema de archivos privada de origen es una variación de la API de acceso al sistema de archivos que está diseñada para proporcionar más privacidad a los usuarios. También permite a las aplicaciones acceder a los archivos del dispositivo del usuario, pero solo dentro de un directorio específico que es privado para el origen de la aplicación. Además, esta API no está pensada para facilitar a los usuarios el acceso al directorio privado mediante el explorador de archivos.

Para abrir un archivo desde el sistema de archivos privados de origen, use la navigator.storage API basada en 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");

Cuota de almacenamiento

En Microsoft Edge, el almacenamiento local y de sesión se limita a unos 5 MB cada uno.

Otros tipos de almacenamiento de datos, como IndexedDB, Cache API o Origin Private File System Access API, pueden usar hasta el 60 % del espacio total en disco en el dispositivo. Por ejemplo, si el dispositivo en el que se ejecuta la aplicación tiene un disco de 64 GB, Microsoft Edge permite que la aplicación almacene hasta unos 38 GB de datos.

Tenga en cuenta que el espacio libre que realmente está disponible en el dispositivo puede ser inferior a la cuota de almacenamiento del 60 %. Por ejemplo, si el dispositivo en el que se ejecuta la aplicación tiene un disco de 64 GB, pero el sistema operativo y otros archivos ya usan 50 GB, la aplicación solo podrá almacenar 14 GB de datos, incluso si la cuota de almacenamiento sigue siendo de 38 GB.

Puede usar navigator.storage.estimate() para preguntar a la API de Storage Manager cuál es la cuota de almacenamiento para el origen de la aplicación y cuánto de ella ya se usa. Para obtener más información, consulte StorageManager.estimate() en MDN.

Al intentar almacenar más datos de los que están disponibles o permitidos, se produce un error de JavaScript. El código debe detectar este error mediante try...catch instrucciones . En el fragmento de código siguiente se muestra cómo detectar un error de cuota superada al almacenar datos mediante Web Storage:

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

Expulsión de datos

Cuando el dispositivo del usuario comienza a tener poco espacio en disco disponible, también conocido como presión de almacenamiento, Microsoft Edge comenzará a expulsar datos no persistentes.

Esto significa que los datos almacenados por la aplicación mediante Cache API, IndexedDB, origin Private File System Access API o Web Storage podrían ser desalojados.

De forma predeterminada, los datos que almacena la aplicación no se consideran persistentes y se pueden expulsar cuando hay presión de almacenamiento. Si la aplicación almacena datos críticos, usa la función para que el navigator.storage.persist() almacenamiento de la aplicación sea persistente. El usuario solo puede borrar el almacenamiento persistente. Para más información, consulte StorageManager.persist() en MDN.