javascript - ejemplo - html5 y bases de datos remotas
Almacenamiento de datos de imagen para aplicaciones web fuera de línea(base de datos de almacenamiento del lado del cliente) (4)
Tengo una aplicación web sin conexión que usa appcaching. Necesito proporcionarle alrededor de 10MB - 20MB de datos que se guardarán (en el lado del cliente) que consisten principalmente en archivos de imágenes PNG. La operación es la siguiente:
- La aplicación web se descarga e instala en la aplicación (utiliza el manifiesto)
- Solicitudes de aplicaciones web desde archivos de datos PNG del servidor (¿cómo? - ver alternativas a continuación)
- Ocasionalmente, la aplicación web se sincroniza con el servidor y realiza pequeñas actualizaciones parciales / eliminaciones / adiciones a la base de datos PNG.
- FYI: El servidor es un servidor JSON REST, que puede colocar archivos en wwwroot para su recolección
Aquí está mi análisis actual de "bases de datos" basadas en el cliente que manejan el almacenamiento de blobs binarios
VER ACTUALIZACIÓN en la parte inferior
- AppCache (a través de manifiesto agregar todos los PNG y luego actualizar a pedido)
- CON: cualquier cambio de un elemento de base de datos PNG significará la descarga completa de todos los elementos en manifiesto (¡Realmente malas noticias!)
- Almacenamiento web
- CON: Diseñado para almacenamiento JSON
- CON: solo puede almacenar blobs a través de la codificación base64 (probablemente una falla fatal debido al costo de descifrado)
- CON: límite de 5MB para webStorage http://htmlui.com/blog/2011-08-23-5-obscure-facts-about-html5-localstorage.html
- PhoneGap y SQLLite
- CON: el patrocinador lo rechazará como una aplicación nativa que requiere certificación
- archivo zip
- El servidor crea un archivo zip, lo coloca en wwwroot y notifica al cliente
- el usuario tiene que descomprimir manualmente (al menos así es como lo veo) y guardarlo en el sistema de archivos del cliente
- La aplicación web usa FileSystem API para referenciar archivos
- CON: ZIP puede ser demasiado grande (zip64?), Mucho tiempo para crear
- CON: No estoy seguro si FileSystem API siempre puede leer fuera de la zona de pruebas (creo)
- Tarjeta USB o SD (de vuelta a la edad de piedra ...)
- El usuario será local en el servidor antes de desconectarse
- Entonces podemos pedirle que inserte una tarjeta SD, que el servidor la complete con archivos PNG
- Luego el usuario lo conectará a la computadora portátil, tableta
- La aplicación web usará FileSystem API para leer los archivos
- CON: No estoy seguro si FileSystem API siempre puede leer fuera de la zona de pruebas (creo)
- WebSQL
- CON: w3c lo ha abandonado (bastante mal)
- Podría considerar un envoltorio de Javascript que usa IndexedDB y WebSQL como un respaldo
- FileSystem API
- Chrome admite lectura / escritura de blobs
- CON: no está claro sobre IE y FireFox (IE10, tiene msSave no estándar)
- caniuse.com informa de la compatibilidad con IOS y Android (pero, nuevamente, ¿esto es solo el r / w de JSON, o incluye la API completa de blob para escribir?
- CON: A los usuarios de Firefox no les gusta la API de FileSystem y no están claros si admiten blobs de ahorro: https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
- PRO: Mucho más rápido que IndexedDB para blobs según jsperf http://jsperf.com/indexeddb-vs-localstorage/15 (página 2)
- IndexedDB
- Buen soporte en IE10, FireFox (guardar, leer blobs)
- Buena velocidad y administración más sencilla que un sistema de archivos (elimina, actualiza)
- PRO: ver pruebas de velocidad: http://jsperf.com/indexeddb-vs-localstorage/15
- Consulte este artículo sobre el almacenamiento y la visualización de imágenes en IndexedDB: https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
- CON: Confirmé que Chrome aún no es compatible con la escritura de blobs (error actual, pero no está claro cuándo se solucionará)
- ACTUALIZACIÓN: ¡Los desarrolladores de Chrome confirman que están trabajando en esto tanto para escritorio como para Android! no hay línea de tiempo todavía.
- LawnChair JavaScript wrapper http://brian.io/lawnchair/
- PRO: envoltorio muy limpio para IndexedDB, WebSQL o cualquier base de datos que tengas (piensa en polyfill)
- CON: no se pueden almacenar blobs binarios, solo datos: uri (codificación base64) (probablemente fallas fatales debido al costo de descifrado)
- IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
- Parashuram ha escrito un buen envoltorio JQUERY para la interfaz IndexedDB sin procesar
- PRO: simplifica mucho el uso de IndexedDB, esperaba agregar un shim / polyfill para Chrome FileSystemAPI
- CON: Debe manejar blobs, pero no pude hacer que funcione
- idb.filesystem.js http://ericbidelman.tumblr.com/post/21649963613/idb-filesystem-js-bringing-the-html5-filesystem-api
- Eric Bidelman @ Google ha escrito un PolyFill bien probado, la API FileSystem que usa la base de datos indexada como un retroceso
- PRO: FileSystem API es ideal para almacenar blobs
- PRO: funciona muy bien en Firefox y Chrome
- PRO: ideal para sincronizar con CouchDB basado en la nube
- CON: no está claro por qué, pero no está funcionando en IE10
- PouchDB JavaScript Library http://pouchdb.com/
- ideal para sincronizar un CouchDB con un DB local (usa WebSQL o IndexedDB (aunque no es mi problema)
- CON: NO CONS, PouchDB ahora admite blobs binarios para todos los navegadores recientes (IE, Chrome, Firefox, Chrome en dispositivos móviles, etc.), así como para muchos navegadores más antiguos. Ese no fue el caso cuando hice esta publicación por primera vez.
NOTA: para ver los datos: codificación uri de PNG, he creado un ejemplo en: http://jsbin.com/ivefak/1/edit
Características deseadas / útiles / innecesarias
- Ninguna aplicación nativa (EXE, PhoneGap, ObjectiveC, etc.) en el cliente (aplicación web pura)
- Solo necesita ejecutarse en las últimas Chrome, FireFox, IE10 para computadoras portátiles
- Fuertemente quiero la misma solución para la tableta Android (IOS sería bueno también) pero solo necesito un navegador para trabajar (FF, Chrome, etc.)
- Rápida población de DB inicial
- REQUISITO: recuperación muy rápida de imágenes por aplicación web desde el almacenamiento (DB, archivo)
- No destinado para los consumidores. Podemos restringir los navegadores y pedirle al usuario que realice una configuración y tareas especiales, pero minimicemos eso
Implementaciones IndexedDB
- Hay un excelente artículo sobre cómo IE, FF y Chrome implementan internamente esto en: http://www.aaron-powell.com/web/indexeddb-storage
- En breve:
- IE utiliza el mismo formato de base de datos que Exchange y Active Directory para IndexedDB
- Firefox está usando SQLite así que están implementando una base de datos NoSQL en la base de datos SQL
- Chrome (y WebKit) están usando una tienda Key / Value que tiene un legado en BigTable
Mis resultados actuales
- Elegí usar un enfoque IndexedDB (y polyfill con FileSystemAPI para Chrome hasta que envíen soporte blob)
- Para buscar las fichas, tuve un dilema, ya que la gente de JQUERY está pensando en agregar esto a AJAX
- Fui con XHR2-Lib por Phil Parsons, que es muy parecido a JQUERY .ajax () https://github.com/p-m-p/xhr2-lib
- Rendimiento para 100MB de descargas (IE10 4s, Chrome 6s, FireFox 7s).
- No pude conseguir que ninguna de las envolturas IndexedDB funcionara para blobs (lawnchair, PouchDB, jquery-indexeddb, etc.)
- Lancé mi propia envoltura, y el rendimiento es (IE10 2s, Chrome 3s, FireFox 10s)
- Con FF, supongo que estamos viendo el problema de rendimiento de usar un DB relacional (sqllite) para un almacenamiento que no sea sql
- NOTA, Chrome tiene excelentes herramientas de depuración (pestaña de desarrollador, recursos) para inspeccionar el estado de IndexedDB.
Resultados FINALES publicados a continuación como respuesta
Actualizar
PouchDB ahora admite blobs binarios para todos los navegadores recientes (IE, Chrome, Firefox, Chrome en dispositivos móviles, etc.), así como para muchos navegadores antiguos. Ese no fue el caso cuando hice esta publicación por primera vez.
Hace unos años (no exactamente la edad de piedra), estaba usando un applet Java firmado que consultaría a su servidor para sincronizar / actualizar los requisitos, descargar los archivos apropiados del servidor y guardarlos en el sistema de archivos del usuario (no en una base de datos). Esa solución podría funcionar para usted, aunque necesitará que alguien escriba el applet y lo firme. Para las soluciones de bases de datos, un applet puede usar el jdbc disponible para la mayoría de las bases de datos usando localhost en un puerto adecuado (por ejemplo, 3306 para MySQL). Creo que la etiqueta del applet está en desuso en Html5 pero aún funciona. No hay experiencia en tabletas Android, por lo que no puedo comentar sobre esa parte.
Para sus requisitos, sugiero que desarrollar un nuevo relleno basado en otros dos: FileSystem API a IndexedDB e IndexedDB a WebSQL : es la mejor opción.
El primero habilitará el soporte para almacenar blobs en Chrome (FileSystem API) y Firefox (IndexedDB), mientras que el último debería proporcionar soporte para Android e iOS ( WebSQL ). Lo que se necesita es simplemente hacer que estos polyfills funcionen juntos, y supongo que no es difícil.
NB: Como no pude encontrar ninguna información en la web sobre esto, debes probar si el almacenamiento de blobs usando el relleno de WebSQL funcionará en iOS y Android. Parece que debería funcionar:
var sql = ["CREATE TABLE", idbModules.util.quote(storeName), "(key BLOB", createOptions.autoIncrement ? ", inc INTEGER PRIMARY KEY AUTOINCREMENT" : "PRIMARY KEY", ", value BLOB)"].join(" ")
Resultados de la caché de blobs sin conexión para mapas deslizantes de PNG
Pruebas
- 171 archivos PNG (total de 3.2MB)
- Plataformas probadas: Chrome v24, FireFox 18, IE 10
- También debería funcionar con Chrome y FF para Android
Recuperar del servidor web
- utilizando XHR2 (compatible con casi todos los navegadores) para la descarga de blobs desde el servidor web
- Fui con XHR2-Lib de Phil Parsons, que es muy parecido a JQUERY .ajax ()
Almacenamiento
- IndexedDB para IE y Firefox
- Chrome: Polyfill (blob almacenado usando FileSystem API, referencia mantenida en IndexedDB) polyfill
- A Debe leer el artículo sobre "Cómo los navegadores almacenan datos IndexedDB"
- Nota: FireFox usa SQLlite para el NOSQL IndexedDB. Esa podría ser la razón del bajo rendimiento. (blobs almacenados por separado)
- Nota: Microsoft IE usa el motor de almacenamiento extensible:
- Nota: Chrome utiliza LevelDB http://code.google.com/p/leveldb/
Monitor
- Estoy usando Leaflet http://leafletjs.com/ para mostrar las fichas del mapa
- Utilicé el plugin de capa de mosaico funcional de Ishmael Smyrnow para buscar la capa de teselas del DB
- Comparé la capa de teselas basada en DB con un almacenamiento puramente local (localhost: //)
- ¡No hay una diferencia notable en el rendimiento! entre usar IndexedDB y archivos locales!
Resultados
- Chrome: Fetch (6.551s), Store (8.247s), Tiempo total transcurrido: (13.714s)
- FireFox: Fetch (0.422s), Store (31.519s), Tiempo transcurrido total: (32.836s)
- IE 10: Fetch (0.668s), Tienda: (0.896s), Tiempo transcurrido total: (3.758s)
Tengo examples caché de mapas (ejemplo abierto, descubrir regiones y acercamientos, cambiar fuera de línea y regiones descubiertas disponibles).
Hay map.js
- capa de mapa para mosaicos sin conexión, storage.js
- implementación de almacenamiento basada en IndexedDb y WebSQL (pero esto solo prueba la implementación con bajo rendimiento).
- Para los archivos del sitio (html, css, js y etc.) prefiero usar el caché de la aplicación.
- Para el almacenamiento prefiero utilizar la base de datos indexada (blob de soporte), Web SQL (solo base64), FileWriter (bloque de soporte, pero solo Chrome). El almacenamiento franco es un gran problema para esto. Necesita la solución de valor clave más rápida que los mezcle a todos. Creo que es una buena decisión usar la solución existente.
- Para buscar, utilicé lienzo con CORS. Pero estoy pensando en WebWorkers y XHR2 y esto puede ser mejor en el lienzo porque Canvas tiene algunos problemas con CORS en diferentes navegadores y otros (por ejemplo, este título se almacenó mal en la ópera ).
Información adicional sobre tamaños para 2 billones de ciudades ( Minsk ):
- Zoom - 9, fichas - 2, tamaño - 52 kb, con anterior - 52 kb;
- Zoom - 10, fichas - 3, tamaño - 72 kb, con anterior - 124 kb;
- Zoom - 11, mosaicos - 7, tamaño - 204 kb, con anterior - 328 kb;
- Zoom - 12, fichas - 17, tamaño - 348 kb, con anterior - 676 kb;
- Zoom - 13, fichas - 48, tamaño - 820 kb, con anterior - 1.5 mb;
- Zoom - 14, fichas - 158, tamaño - 2.2 mb, con anterior - 3.7 mb;
- Zoom - 15, fichas - 586, tamaño - 5.5 mb, con anterior - 9.3 mb;
- Zoom - 16, fichas - 2264, tamaño - 15 mb, con anterior - 24.3 mb;