Almacenamiento para la Web

Existen muchas opciones diferentes para almacenar datos en el navegador. ¿Cuál es el mejor para tus necesidades?

Las conexiones a Internet pueden ser débiles o inexistentes sobre la marcha, por eso el soporte sin conexión y el rendimiento confiable son características comunes en aplicaciones web progresivas. Incluso con una conexión inalámbrica perfecta el uso sensato del almacenamiento en caché y de otras técnicas de almacenamiento mejorar considerablemente la experiencia del usuario. Existen varias formas de almacenar en caché los recursos estáticos de tu aplicación (HTML, JavaScript, CSS, imágenes, etc.) y datos (datos del usuario, artículos de noticias, etc.). Pero ¿cuál es la mejor solución? Cómo ¿cuánto puedes almacenar? ¿Cómo evitan su expulsión?

¿Qué debo usar?

Esta es una recomendación general para almacenar recursos:

IndexedDB y la API de Cache Storage son compatibles con todos los navegadores modernos. Ambos son asíncronos y no bloquearán el subproceso principal. Son accesibles desde el objeto window, los trabajadores web y los service workers, lo que hace que te resultará fácil usarlos en cualquier parte de tu código.

¿Qué ocurre con otros mecanismos de almacenamiento?

Existen muchos otros mecanismos de almacenamiento disponibles en el navegador, pero tienen un uso limitado y pueden causar problemas de rendimiento significativos.

SessionStorage es específico de una pestaña y se limita a las la vida útil de la pestaña. Puede ser útil para almacenar cantidades pequeñas de sesiones información específica, como una clave IndexedDB. Se debe usar con cautela porque es síncrono y bloqueará el subproceso principal. Sí tiene un límite de 5 MB y puede contener solo cadenas. Como es específica de cada pestaña, No se puede acceder a él desde trabajadores web o service workers.

Se debe evitar LocalStorage porque es síncrono. y bloqueará el subproceso principal. Tiene un límite de 5 MB y puede contener solo cadenas. No se puede acceder a LocalStorage con trabajadores web o servicios trabajadores.

Las cookies tienen sus usos, pero no se deben utilizar para el almacenamiento. Las cookies se envían con cada solicitud HTTP, así que almacenar más de un una pequeña cantidad de datos aumentará significativamente el tamaño de cada solicitud web. Son síncronos y no se puede acceder a ellos desde los trabajadores web. Me gusta LocalStorage y SessionStorage, las cookies se limitan solo a cadenas.

La API de File System y la API de FileWriter proporcionan métodos para leer y escribir archivos en un sistema de archivos de zona de pruebas. Si bien es asíncrono, no se recomienda porque es solo disponible en navegadores con Chromium.

La API de File System Access se diseñó para que fuera para que los usuarios lean y editen archivos en su sistema local. El usuario Debe otorgar permiso para que una página pueda leer o escribir en cualquier archivo local. los permisos no persisten en todas las sesiones.

No se debe usar WebSQL, y el uso existente debe migrarse a IndexedDB Se quitó la compatibilidad con casi todos los principales navegadores. El W3C dejó de mantener la especificación de Web SQL en 2010, y no planeamos realizar más actualizaciones.

No se debe usar la caché de aplicaciones, y el uso actual sí debe migrados a service workers y a la API de Cache. Ha sido obsoleto y se quitará la compatibilidad de los navegadores en el futuro.

¿Cuánto puedo almacenar?

En resumen, mucho, al menos un par de cientos de megabytes y, posiblemente, cientos de gigabytes o más. Las implementaciones del navegador varían, pero la cantidad de almacenamiento disponible suele basarse en la cantidad de almacenamiento disponible en la dispositivo.

  • Chrome permite que el navegador use hasta el 80% del espacio total del disco. Un origen puede usan hasta un 60% del espacio total del disco. Puedes usar StorageManager API para determinar la cuota máxima disponible. Otras aplicaciones basadas en Chromium navegadores pueden ser diferentes.
    • En el modo Incógnito, Chrome reduce la cantidad de almacenamiento que puede usar un origen cerca del 5% del espacio total en el disco.
    • Si el usuario habilitó la opción "Borrar cookies y datos de sitios al cerrar todas ventanas" en Chrome, la cuota de almacenamiento se reduce y un máximo de 300 MB.
    • Consulta el documento PR 3896 para detalles sobre la implementación de Chrome.
  • Internet Explorer 10 y versiones posteriores pueden almacenar hasta 250 MB y le indicarán al cuando se usan más de 10 MB.
  • Firefox permite que el navegador utilice hasta un 50% del espacio libre en el disco. Los eTLD+1 grupo (p.ej., example.com, www.example.com y foo.bar.example.com) puede usar hasta 2 GB. Puedes usar la API de StorageManager para determinar cuánto espacio queda disponibles.
  • Safari (en computadoras de escritorio y en dispositivos móviles) parece permitir aproximadamente 1 GB. Cuando el límite cuando se alcance, Safari le solicitará al usuario que aumentará el límite en 200 MB en incrementos graduales. No pudimos encontrar documentación oficial sobre este tema.
    • Si se agrega una AWP a la pantalla de inicio en Safari para dispositivos móviles, aparecerá crear un nuevo contenedor de almacenamiento y la AWP no comparta nada y Safari para dispositivos móviles. Una vez que se alcanza la cuota de una AWP instalada, no parece haber forma de solicitar almacenamiento adicional.

Antes, si un sitio excedía cierto umbral de datos almacenados, el navegador le pedirá al usuario que otorgue permiso para usar más datos. Para Por ejemplo, si el origen usó más de 50 MB, el navegador le pedirá al usuario para almacenar hasta 100 MB. Luego, vuelve a preguntar en incrementos de 50 MB.

Hoy en día, la mayoría de los navegadores actualizados no le preguntan al usuario y permiten que un sitio que usen la nube hasta la cuota asignada. La excepción parece ser Safari, que un mensaje cuando se supera la cuota de almacenamiento y solicita permiso para aumentar la cuota asignada. Si un origen intenta usar más de la cuota asignada y otros intentos de escribir datos fallarán.

¿Cómo puedo comprobar cuánto almacenamiento hay disponible?

En muchos navegadores, puedes usar el API de StorageManager para determinar la cantidad de almacenamiento disponibles para el origen y la cantidad de almacenamiento que usa. Informa el total de bytes que usan IndexedDB y la API de Cache, y permite para calcular el espacio de almacenamiento restante aproximado.

if (navigator.storage && navigator.storage.estimate) {
  const quota = await navigator.storage.estimate();
  // quota.usage -> Number of bytes used.
  // quota.quota -> Maximum number of bytes available.
  const percentageUsed = (quota.usage / quota.quota) * 100;
  console.log(`You've used ${percentageUsed}% of the available storage.`);
  const remaining = quota.quota - quota.usage;
  console.log(`You can write up to ${remaining} more bytes.`);
}

StorageManager aún no se implemented en todos los navegadores, por lo que debe detectarla antes de usarla. Incluso cuando está disponible, debes detectar errores de cuota superada (consulta a continuación). En algunos casos, es posible que la cuota disponible supere la cantidad real de almacenamiento disponible.

Inspeccionar

Durante el desarrollo, puedes usar las Herramientas para desarrolladores de tu navegador para inspeccionar la distintos tipos de almacenamiento y borrar fácilmente todos los datos almacenados.

Se agregó una nueva función en Chrome 88 que permite anular el almacenamiento del sitio en el panel de almacenamiento. Esta función te permite simular en diferentes dispositivos y prueba el comportamiento de tus apps en discos de baja disponibilidad reales. Ve a Aplicación y, luego, a Almacenamiento, habilita las Simular cuota de almacenamiento personalizada y, luego, ingresar un número válido para para simular la cuota de almacenamiento.

Panel Storage de Herramientas para desarrolladores

Mientras trabajaba en este artículo, escribí una herramienta simple para para usar rápidamente tanto almacenamiento como sea posible. Es una forma rápida y fácil para experimentar con distintos mecanismos de almacenamiento y ver de que consumas toda la cuota.

¿Cómo manejar el exceso de cuota?

¿Qué debes hacer cuando superas la cuota? Lo más importante es que debes detectar y manejar errores de escritura, ya sea un QuotaExceededError o o algo más. Luego, según el diseño de tu aplicación, decide cómo manejarlo. Por ejemplo, borra contenido al que no se haya accedido en mucho tiempo, quita según el tamaño, o brindan una forma para que los usuarios elijan lo que desean borrar.

Tanto IndexedDB como la API de Cache muestran una DOMError llamada QuotaExceededError cuando superes la cuota disponible.

IndexedDB

Si el origen superó su cuota, los intentos de escribir en IndexedDB fallan. Se llamará al controlador onabort() de la transacción y se pasará un evento. El evento incluirá un DOMException en la propiedad de error. Verificando el el error name mostrará QuotaExceededError.

const transaction = idb.transaction(['entries'], 'readwrite');
transaction.onabort = function(event) {
  const error = event.target.error; // DOMException
  if (error.name == 'QuotaExceededError') {
    // Fallback code goes here
  }
};

API de Cache

Si el origen excedió su cuota, intenta escribir en la API de Cache se rechazará con un DOMException QuotaExceededError.

try {
  const cache = await caches.open('my-cache');
  await cache.add(new Request('/sample1.jpg'));
} catch (err) {
  if (error.name === 'QuotaExceededError') {
    // Fallback code goes here
  }
}

¿Cómo funciona una expulsión?

El almacenamiento web se clasifica en dos categorías: “Mejor esfuerzo” y “persistente”. El mejor esfuerzo implica que el navegador puede liberar el almacenamiento sin que interrumpen al usuario, pero son menos duraderas para los datos críticos o a largo plazo. El almacenamiento persistente no se borra automáticamente cuando hay poco. El usuario necesita liberar este almacenamiento manualmente (en la configuración del navegador).

De forma predeterminada, los datos de un sitio (como IndexedDB, Cache API, etc.) la categoría de mejor esfuerzo, lo que significa que, a menos que un sitio tenga almacenamiento persistente solicitado, el navegador puede expulsar datos de sitios a su discreción, por ejemplo, cuando el almacenamiento del dispositivo es bajo.

La política de expulsión según el mejor esfuerzo es la siguiente:

  • Los navegadores basados en Chromium comenzarán a expulsar datos cuando se agoten de espacio, borrando primero todos los datos del sitio desde el origen menos utilizado y luego al siguiente, hasta que el navegador deje de superar el límite.
  • Internet Explorer 10+ no expulsará los datos, pero evitará que el origen escribir más.
  • Firefox comenzará a expulsar datos cuando el espacio disponible en el disco se llene, borrar primero todos los datos del sitio desde el origen menos utilizado; luego, a continuación, hasta que el navegador ya no supere ese límite.
  • Safari no expulsaba datos, pero recientemente implementó una nueva límite de siete días para todo el almacenamiento con capacidad de escritura (consulta a continuación).

A partir de iOS y iPadOS 13.4 y Safari 13.1 en macOS, hay una límite de siete días para todo el almacenamiento que admite escritura de secuencias de comandos, el registro de trabajadores y la API de Cache. Safari expulsará todos contenido de la caché después de siete días de uso de Safari si el usuario no lo hace interactuar con el sitio. Esta política de expulsión no se aplica a aplicaciones instaladas AWP que se agregaron a la pantalla principal. Consulta Bloqueo completo de cookies de terceros y mucho más en WebKit para ver todos los detalles.

Contenido adicional: Por qué usar un wrapper para IndexedDB

IndexedDB es una API de bajo nivel que requiere una configuración significativa antes de usarla. lo que puede ser particularmente difícil para almacenar datos simples. A diferencia de la mayoría de las APIs basadas en promesas y eventos. Wrappers de promesas como: idb para IndexedDB oculta algunas de las funciones potentes, pero más Lo más importante es ocultar la maquinaria compleja (por ejemplo, transacciones o control de versiones de esquemas). que incluye la biblioteca IndexedDB.

Conclusión

Se acabaron los días de almacenamiento limitado y la necesidad de pedirle al usuario que almacenara más más datos. Los sitios pueden almacenar eficazmente todos los recursos y datos que que se deben ejecutar. Con la API de StorageManager, puedes determinar cuánto tienes disponible y cuánto usaste. Además, con almacenamiento persistente, a menos que el usuario lo quite, pueda protegerlo de su expulsión.

Recursos adicionales

Gracias

Queremos dar un agradecimiento especial a Jarryd Goodman, Phil Walton, Eiji Kitamura, Daniel Murphy, Darwin Huang, Josh Bell, Marijn Kruisselbrink y Victor Costan por su opinión este artículo. Gracias a Eiji Kitamura, Addy Osmani y Marc Cohen, quienes escribieron los artículos originales en los que se basa. Eiji escribió una herramienta útil llamado Abusuario de almacenamiento del navegador, que fue útil para validar comportamiento actual. Te permite almacenar la mayor cantidad de datos posible y ver la límites de almacenamiento en tu navegador. Gracias a Francois Beaufort que hizo la excavación a Safari para conocer los límites de almacenamiento.

La imagen hero es de Guillaume Bolduc en Detallar.