Missed the action at this year's Chrome Dev Summit? Catch up with our playlist on YouTube. Watch now.

Almacenamiento sin conexión para Progressive Web Apps

PWA en DevTools
La Progressive Web App de Pokedex utiliza IndexedDB para el estado de la app y el conjunto de datos de los pokemon, mientras que la Cache API se usa para recursos localizables mediante URL.

Cuando te trasladas de un lugar a otro, las conexiones de Internet pueden ser débiles o inexistentes. Por eso, ofrecer compatibilidad y un rendimiento confiable sin conexión es una característica común de las apps web progresivas. Incluso en entornos con perfectas conexiones inalámbricas, el uso sensato de almacenamiento en caché y de otras técnicas de almacenamiento puede mejorar considerablemente la experiencia del usuario. En esta publicación, resumiremos algunas ideas sobre el almacenamiento de datos sin conexión de las PWA (piensa en las cargas JSON, las imágenes y los datos estáticos generales necesarios para brindar una valiosa experiencia sin conexión).

Recomendación

Vayamos directamente al grano con una recomendación global para almacenar datos sin conexión:

Este es el fundamento:

Ambas API son asíncronas (IndexedDB está basada en eventos y Cache API, en promesas). También funcionan con Web Workers, y Window y Service Workers. IndexedDB se encuentra disponible en todos lados. Los Service Workers (y la Cache API) ahora se encuentran disponibles en Chrome, Firefox y Opera, y están en desarrollo para Edge. Los contenedores de promesas de IndexedDB ocultan algunos de los mecanismos potentes, pero complejos (p. ej., transacciones y versiones de esquemas), que se incluyen en la biblioteca de IndexedDB. IndexedDB admitirá observadores, que posibilitan una sincronización simple entre pestañas.

Safari 10 corrigió varios errores antiguos de IndexedDB en sus últimas Technology Preview. NOTA: Algunas personas tuvieron problemas de estabilidad con IndexedDB y PouchDB en Safari 10, y lo consideran un poco lento. Hasta que se investigue más sobre el tema, tu recorrido puede variar. Prueba los errores del navegador y repórtalos para que la gente de @webkit y otros autores de bibliotecas de OSS puedan examinarlos. De forma predeterminada, LocalForage, PouchDB, YDN y Lovefield usan WebSQL en Safari (debido a que no hay una forma eficaz de probar características defectuosas en IndexedDB). Esto significa que estas bibliotecas funcionarán en Safari 10 sin esfuerzo adicional (solo que sin usar IndexedDB directamente).

Para las PWA, puedes almacenar en caché los recursos estáticos, usando Cache API para componer la shell de tu app (archivos JS/CSS/HTML), y completar los datos de la página sin conexión desde IndexedDB. Ahora se puede depurar IndexedDB en Chrome (pestaña Application), Opera, Firefox (Storage Inspector) y Safari (consulta la pestaña Storage).

¿Qué ocurre con otros mecanismos de almacenamiento?

El almacenamiento web (p. ej., LocalStorage y SessionStorage) es sincrónico, no admite Web Workers, y tiene límites de tamaño y tipo (solo strings). Las cookies son útiles para algunas cosas, pero son sincrónicas, no admiten Web Workers y también tienen límites de tamaño. WebSQL no es compatible con varios navegadores y no se recomienda usarlo. La File System API no es compatible con ningún navegador, excepto Chrome. La File API se está mejorando en la File and Directory Entries API y en las especificaciones de File API, pero ninguna es lo suficientemente madura o está estandarizada para incentivar una adopción a gran escala.

¿Cuánto puedo almacenar?

Navegador Límite
Chrome <6% del espacio libre
Firefox <10% del espacio libre
Safari <50 MB
IE10 <250 MB

En Chrome y Opera, el almacenamiento es por origen (y no por API). Ambos mecanismos de almacenamiento permitirán almacenar datos hasta alcanzar la cuota del navegador. Las apps pueden controlar la cuota que utilizan con la Quota Management API. En Chrome, las apps pueden usar hasta un 6% del espacio libre en el disco. En Firefox, las apps pueden usar hasta un 10% del espacio libre en el disco, pero le avisará al usuario cuando se solicite almacenamiento después de haber almacenado 50 MB de datos. En Safari para dispositivos móviles, las apps pueden usar un máximo de 50 MB, mientras que en la versión de escritorio, el almacenamiento es ilimitado (con advertencias después de los 5 MB). El máximo de IE10 es 250 MB y le advierte al usuario después de 10 MB. PouchDB realiza un seguimiento del comportamiento del almacenamiento de IDB.

¿Cómo puedo averiguar la cantidad de espacio de almacenamiento que utiliza mi app?

En Chrome, la Quota Management API te permite consultar la cantidad de espacio de almacenamiento actualmente en uso y cuánto tiene disponible la app. Una Storage Quota Estimate API más nueva usa promesas para que sea aún más fácil averiguar la cuota que utiliza el origen.

¿Cómo funciona el descarte de caché?

Navegador Política de descarte
Chrome LRU cuando Chrome se queda sin espacio
Firefox LRU cuando el disco está lleno
Safari Sin descarte
Edge Sin descarte

A los orígenes, se les atribuye una cantidad de espacio para que utilicen como deseen. Todos los mecanismos de almacenamiento de origen (IndexedDB, Cache API, localStorage, etc.) comparten este espacio libre. No se especifica la cantidad asignada, y variará según condiciones del dispositivo y condiciones de almacenamiento.

Cuando queda poco almacenamiento web, un usuario-agente libera espacio de almacenamiento. Esto puede tener un impacto en las respuestas sin conexión. En consecuencia, la recientemente actualizada especificación de Storage define estrategias “persistentes” y de “mejor esfuerzo” (esta última es la estrategia predeterminada). “Mejor esfuerzo” significa que el almacenamiento se puede liberar sin interrumpir al usuario, pero es menos duradera para datos a largo plazo o críticos. Actualmente, tanto IndexedDB como la Cache API se encuentran en la categoría de “mejor esfuerzo”.

El almacenamiento “persistente” no se libera automáticamente cuando hay poco espacio. El usuario debe liberar manualmente este almacenamiento (a través de configuraciones del navegador). Chrome ha estado experimentando con la compatibilidad con almacenamiento persistente en una prueba de origen y las últimas novedades sugieren que se incluirá en Chrome 55.

Recursos actuales y futuros del almacenamiento sin conexión

Si te interesa el almacenamiento sin conexión, te recomendamos los siguientes recursos.

  • Almacenamiento duradero: protege el almacenamiento de las políticas de eliminación de datos del usuario-agente.

  • Indexed Database API 2.0: gestión avanzada de datos clave-valor.

  • IndexedDB con promesas: compatibilidad nativa con una versión de IndexedDB apta para promesas.

  • Observadores de IndexedDB: observación de IndexedDB nativa sin necesidad de contenedores en la base de datos.

  • Async Cookies API: API de cookies de JavaScript asíncrona para documentos y workers.

  • Quota Management API: permite conocer la cantidad de cuota que una app o un origen está utilizando.

  • writable-files: permite que los sitios interactúen con los archivos locales de forma más dinámica.

  • Descargas de directorios: permite que los sitios descarguen directorios sin archivos .zip.

  • File and Directory Entries API: permite cargar archivos y directorios mediante la función de arrastrar y colocar.

  • Se está esbozando una Async Cookies API con polyfill en desarrollo.

  • Actualmente, Edge no admite la depuración de IndexedDB (sin embargo, es posible depurar el JetDB subyacente). Puedes votar aquí para solicitar que se incorpore la compatibilidad.

  • Aunque ya se han debatido ideas sobre LocalStorage asíncrono, la atención se centra, actualmente, en mejorar el estado de IndexedDB 2.0.

  • Es posible que, en un futuro, la propuesta de writable-files nos brinde una solución en vía de estandarización que nos permita interactuar con archivos locales sin problema.

  • Para las apps que requieran almacenamiento más persistente, consulta el desarrollo actual del almacenamiento duradero.

El almacenamiento sin conexión no es algo mágico; si conoces las API subyacentes, te será más fácil aprovechar al máximo los recursos disponibles actualmente. Tanto si prefieres usar directamente estas API o trabajar con una biblioteca de abstracción, es conveniente que te tomes un tiempo para familiarizarte con las opciones.

¡Esperamos que esta guía te ayude a desarrollar una experiencia sin conexión que haga brillar a tu PWA! ✨

Lectura adicional

Recursos útiles

  • sw-toolbox (almacenamiento en caché sin conexión para solicitudes dinámicas/en tiempo de ejecución)

  • sw-precache (almacenamiento previo en caché sin conexión para shells de recursos estáticos/aplicaciones)

  • Posibilidad de los usuarios de webpack de usar los elementos anteriores u offline-plugin

Bibliotecas de IndexedDB que vale la pena investigar

Gracias a Nolan Lawson, Joshua Bell (su trabajo sobre almacenamiento libre en la web y su presentación en BlinkOn inspiraron mucho este artículo), Jake Archibald, Dru Knox y otros por su labor anterior sobre espacio de almacenamiento en la web.