Saltar al contenido principal




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


Actualizado

Las conexiones a Internet pueden ser defectuosas o inexistentes mientras viaja, por lo que el soporte sin conexión y el rendimiento confiable son características comunes en las aplicaciones web progresivas. Incluso en entornos inalámbricos perfectos, el uso prudente del almacenamiento en caché y otras técnicas de almacenamiento puede mejorar sustancialmente la experiencia del usuario. Hay varias formas de almacenar en caché los recursos de la aplicación estática (HTML, JavaScript, CSS, imágenes, etc.) y los datos (datos de usuario, artículos de noticias, etc.). ¿Pero cuál es la mejor solución? ¿Cuánto puedes almacenar? ¿Cómo evitas que sea desalojado?

¿Qué debo usar?

Aquí hay una recomendación general para almacenar recursos:

IndexedDB y la API de almacenamiento en caché son compatibles con todos los navegadores modernos. Ambos son asincrónicos y no bloquearán el hilo principal. Son accesibles desde el window Object, Web Workers y Service Workers, lo que facilita su uso en cualquier parte del código.

¿Qué pasa con otros mecanismos de almacenamiento?

Hay varios otros mecanismos de almacenamiento disponibles en el navegador, pero tienen un uso limitado y pueden causar problemas de rendimiento importantes.

Almacenamiento de sesión es específico de la pestaña y se ajusta a la vida útil de la pestaña. Puede ser útil para almacenar pequeñas cantidades de información específica de la sesión, por ejemplo, una clave IndexedDB. Debe usarse con precaución porque es sincrónico y bloqueará el hilo principal. Está limitado a unos 5 MB y solo puede contener cadenas. Debido a que es específico de una pestaña, los trabajadores web o los trabajadores de servicios no pueden acceder a él.

Almacenamiento local debe evitarse porque es sincrónico y bloqueará el hilo principal. Está limitado a unos 5 MB y solo puede contener cadenas. LocalStorage no es accesible para trabajadores web o trabajadores de servicios.

Galletas tienen sus usos, pero no deben usarse para almacenamiento. Las cookies se envían con cada solicitud HTTP, por lo que almacenar algo más que una pequeña cantidad de datos aumentará significativamente el tamaño de cada solicitud web. Son síncronos y los trabajadores web no pueden acceder a ellos. Al igual que LocalStorage y SessionStorage, las cookies se limitan solo a cadenas.

los API del sistema de archivos y la API de FileWriter proporcionan métodos para leer y escribir archivos en un sistema de archivos de espacio aislado. Si bien es asincrónico, no se recomienda porque es
solo disponible en navegadores basados ​​en Chromium.

La API de acceso al sistema de archivos se diseñó para facilitar a los usuarios la lectura y edición de archivos en su sistema de archivos local. El usuario debe otorgar permiso antes de que una página pueda leer o escribir en cualquier archivo local, y los permisos no se conservan entre sesiones.

WebSQL debería no ser utilizado, y el uso existente se debe migrar a IndexedDB. El apoyo tiene ha sido eliminado de casi todos los principales navegadores. El W3C dejó de mantener la especificación Web SQL en 2010, sin planes de actualizaciones adicionales previstas.

La caché de la aplicación debe no y el uso existente se debe migrar a los trabajadores del servicio y la API de caché. Ha sido
obsoleto y la compatibilidad se eliminará de los navegadores en el futuro.

¿Cuánto puedo almacenar?

En breve, mucho, al menos un par de cientos de megabytes y potencialmente cientos de gigabytes o más. Las implementaciones del navegador varían, pero la cantidad de almacenamiento disponible generalmente se basa en la cantidad de almacenamiento disponible en el dispositivo.

  • Chrome permite que el navegador utilice hasta el 80% del espacio total en disco. Un origen puede utilizar hasta el 60% del espacio total en disco. Puede utilizar la API de StorageManager para determinar la cuota máxima disponible. Otros navegadores basados ​​en Chromium pueden permitir que el navegador utilice más almacenamiento. Consulte PR # 3896 para obtener detalles sobre la implementación de Chrome.
  • Internet Explorer 10 y versiones posteriores pueden almacenar hasta 250 MB y le avisará al usuario cuando se hayan utilizado más de 10 MB.
  • Firefox permite que el navegador utilice hasta el 50% del espacio libre en disco. Un
    eTLD + 1
    grupo (por ejemplo, example.com, www.example.com y foo.bar.example.com)
    puede usar hasta 2GB. Puede utilizar la API de StorageManager para determinar cuánto espacio queda disponible.
  • Safari (tanto de escritorio como móvil) parece permitir hasta 1 GB. Cuando se alcanza el límite, Safari le pedirá al usuario que aumente el límite en incrementos de 200 MB. No pude encontrar ninguna documentación oficial sobre esto.

En el pasado, si un sitio excedía un cierto umbral de datos almacenados, el navegador solicitaba al usuario que concediera permiso para utilizar más datos. Por ejemplo, si el origen usó más de 50 MB, el navegador le pedirá al usuario que le permita almacenar hasta 100 MB y luego volverá a preguntar en incrementos de 50 MB.

Hoy en día, la mayoría de los navegadores modernos no avisarán al usuario y permitirán que un sitio utilice hasta su cuota asignada. La excepción parece ser Safari, que solicita 750 MB y solicita permiso para almacenar hasta 1,1 GB. Si un origen intenta usar más de su cuota asignada, fallarán los intentos posteriores de escribir datos.

¿Cómo puedo comprobar la cantidad de almacenamiento disponible?

En muchos navegadores, puedes usar el
API de StorageManager para determinar la cantidad de almacenamiento disponible para el origen y cuánto almacenamiento está usando. Informa el número total de bytes utilizados por IndexedDB y la API de caché, y permite calcular el espacio de almacenamiento restante aproximado disponible.

if (navigator.storage && navigator.storage.estimate) {
const quota = await navigator.storage.estimate();
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 no es implementado en todos los navegadores todavía, por lo que debe detectarlo antes de usarlo. Incluso cuando está disponible, debe detectar errores por exceso de cuota (ver más abajo). En algunos casos, es posible que la cuota disponible exceda la cantidad real de almacenamiento disponible.

Otros navegadores basados ​​en Chromium pueden tener en cuenta la cantidad de espacio libre al informar la cuota disponible. Chrome no lo hace y siempre informará el 60% del tamaño real del disco. Esto ayuda a reducir la capacidad de determinar el tamaño de los recursos de origen cruzado almacenados.

Inspeccionar

Durante el desarrollo, puede usar DevTools de su navegador para inspeccionar los diferentes tipos de almacenamiento y borrar fácilmente todos los datos almacenados.

storage-test-tool-4845895

Mientras trabajaba en este artículo, escribí un herramienta simple para intentar utilizar rápidamente tanto almacenamiento como sea posible. Es una forma rápida y sencilla de experimentar con diferentes mecanismos de almacenamiento y ver qué sucede cuando usas toda tu cuota.

¿Cómo manejar el exceso de cuota?

¿Qué debe hacer cuando supere la cuota? Lo más importante es que siempre debe detectar y manejar los errores de escritura, ya sea QuotaExceededError o algo mas. Luego, dependiendo del diseño de su aplicación, decida cómo manejarlo. Por ejemplo, elimine el contenido al que no se ha accedido en mucho tiempo, elimine datos según el tamaño o proporcione una forma para que los usuarios elijan lo que desean eliminar.

Tanto IndexedDB como Cache API arrojan un DOMError llamado
QuotaExceededError cuando haya superado la cuota disponible.

IndexedDB

Si el origen ha superado su cuota, los intentos de escribir en IndexedDB fallarán. La transacción onabort() handler será llamado, pasando un evento. El evento incluirá un DOMException en la propiedad de error. Comprobando el error name volverá QuotaExceededError.

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

API de caché

Si el origen ha superado su cuota, los intentos de escribir en la API de caché se rechazarán con un QuotaExceededError DOMException.

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

¿Cómo funciona el desalojo?

El almacenamiento web se clasifica en dos categorías, «Mejor esfuerzo» y «Persistente». El mejor esfuerzo significa que el navegador puede borrar el almacenamiento sin interrumpir al usuario, pero es menos duradero para datos críticos o de largo plazo. El almacenamiento persistente no se borra automáticamente cuando el almacenamiento es bajo. El usuario debe borrar manualmente este almacenamiento (a través de la configuración del navegador).

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

La política de desalojo por mejor esfuerzo es:

  • Los navegadores basados ​​en Chromium comenzarán a desalojar los datos cuando el navegador se quede sin espacio, borrando todos los datos del sitio del origen menos recientemente utilizado primero, luego el siguiente, hasta que el navegador ya no supere el límite.
  • Internet Explorer 10+ no desalojará los datos, pero evitará que el origen escriba más.
  • Firefox comenzará a desalojar los datos cuando se llene el espacio disponible en el disco, borrando todos los datos del sitio del origen que se utilizó menos recientemente, luego el siguiente, hasta que el navegador ya no supere el límite.
  • Safari anteriormente no desalojaba datos, pero recientemente implementó un nuevo límite de siete días en todo el almacenamiento de escritura (ver a continuación).

A partir de iOS y iPadOS 13.4 y Safari 13.1 en macOS, existe un límite de siete días en todo el almacenamiento de escritura de scripts, incluido IndexedDB, el registro del trabajador del servicio y la API de caché. Esto significa que Safari desalojará todo el contenido de la caché después de siete días de uso de Safari si el usuario no interactúa con el sitio. Esta política de desalojo no se aplica a las PWA instaladas que se han agregado a la pantalla de inicio. Ver
Bloqueo completo de cookies de terceros y más en el blog de WebKit para obtener detalles completos.

Puede solicitar almacenamiento persistente para su sitio a fin de proteger datos críticos de aplicaciones o usuarios.

Bono: ¿Por qué usar un contenedor para IndexedDB?

IndexedDB es una API de bajo nivel que requiere una configuración significativa antes de su uso, lo que puede ser particularmente doloroso para almacenar datos simples. A diferencia de la mayoría de las API modernas basadas en promesas, se basa en eventos. Envoltorios de promesas como
idb para IndexedDB esconde algunas de las funciones poderosas pero, lo que es más importante, oculta la maquinaria compleja (por ejemplo, transacciones, control de versiones de esquemas) que viene con la biblioteca IndexedDB.

Conclusión

Atrás quedaron los días de almacenamiento limitado y de incitar al usuario a almacenar más y más datos. Los sitios pueden almacenar de forma eficaz todos los recursos y datos que necesitan para funcionar. Utilizando el API de StorageManager puede determinar cuánto está disponible para usted y cuánto ha usado. Y con
almacenamiento persistente, a menos que el usuario lo elimine, puede protegerlo del desalojo.

Recursos adicionales

Gracias

Un agradecimiento especial a Jarryd Goodman, Phil Walton, Eiji Kitamura, Daniel Murphy, Darwin Huang, Josh Bell, Marijn Kruisselbrink y Victor Costan por revisar 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 llamada Abusador de almacenamiento del navegador que fue útil para validar el comportamiento actual. Le permite almacenar tantos datos como sea posible y ver los límites de almacenamiento en su navegador. Gracias a Francois Beaufort, que investigó Safari para averiguar sus límites de almacenamiento.

La imagen del héroe es de Guillaume Bolduc en
Unsplash.