web-dev-qa-db-fra.com

Stockage des données d'image pour une application Web hors connexion (base de données de stockage côté client)

J'ai une application web hors ligne utilisant appcaching. J'ai besoin de lui fournir environ 10 Mo - 20 Mo de données qu'il sauvegardera (côté client), principalement des fichiers image PNG. L'opération est la suivante:

  1. Application Web téléchargée et installée dans appcache (utilise le manifeste)
  2. Demandes d'application Web à partir de fichiers de données PNG de serveur (comment? - voir les alternatives ci-dessous)
  3. De temps en temps, les applications Web se resynchronisent avec le serveur et effectuent de petites mises à jour/suppressions/ajouts partiels à la base de données PNG.
  4. FYI: le serveur est un serveur JSON REST, qui peut placer des fichiers dans wwwroot pour le ramassage

Voici mon analyse actuelle des "bases de données" basées sur le client qui gèrent le stockage de blob binaire

VOIR MISE À JOUR en bas

  • AppCache (via manifeste, ajoutez tous les fichiers PNG puis mettez à jour à la demande)
    • CON: tout changement d'un élément de la base de données PNG signifiera le téléchargement complet de tous les éléments du manifeste (Vraiment mauvaise nouvelle!)
  • WebStorage
  • PhoneGap & SQLLite
    • CON: le sponsor le rejettera comme une application native nécessitant une certification
  • Fichier zip
    • Le serveur crée un fichier Zip, le place dans wwwroot et avise le client
    • l'utilisateur doit décompresser manuellement (du moins, c'est comme ça que je le vois) et l'enregistrer dans le système de fichiers du client
    • L'application Web utilise l'API FileSystem pour référencer les fichiers
    • CON: Zip est peut-être trop grand (Zip64?), Il est long de créer
    • CON: Pas sûr si l'API FileSystem peut toujours lire dans le bac à sable (je pense que oui)
  • USB ou carte SD (retour à l'âge de pierre ....)
    • L'utilisateur sera local sur le serveur avant de se déconnecter
    • Donc, nous pourrions lui faire insérer une carte SD, laisser le serveur la remplir avec des fichiers PNG
    • Ensuite, l'utilisateur va le brancher sur l'ordinateur portable, tablette
    • L'application Web utilisera l'API FileSystem pour lire les fichiers
    • CON: Pas sûr si l'API FileSystem peut toujours lire dans le bac à sable (je pense que oui)
  • WebSQL
    • CON: w3c l'a abandonné (assez mauvais)
    • Je pourrais envisager un wrapper Javascript qui utilise IndexedDB et WebSQL comme solution de secours
  • API FileSystem
    • Chrome prend en charge la lecture/écriture des blobs
    • CON: pas clair sur IE et FireFox (IE10, a msSave non standard)
    • caniuse.com rapporte IOS et Android support (mais encore une fois, s’agit-il seulement de r/w de JSON, ou inclut-il l’API de blob complète pour l’écriture?)?
    • CON: les gens de FireFox n'aiment pas l'API FileSystem et ne savent pas s'ils prennent en charge la sauvegarde des blobs: https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
    • PRO: beaucoup plus rapide que IndexedDB pour les blobs selon jsperf http://jsperf.com/indexeddb-vs-localstorage/15 (page 2)
  • IndexedDB
    • Bon support dans IE10, FireFox (sauvegarder, lire les blobs)
    • Bonne vitesse et gestion plus facile qu'un système de fichiers (suppressions, mises à jour)
    • PRO: voir tests de vitesse: http://jsperf.com/indexeddb-vs-localstorage/15
    • Voir cet article sur le stockage et l'affichage d'images dans IndexedDB: https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
    • CON: j'ai confirmé que Chrome ne supporte pas encore l'écriture de blob (bogue actuel, mais ne sait pas quand il sera corrigé)
    • UPDATE: Chrome confirment qu’ils travaillent sur cette question, tant pour le bureau que pour Android! Il n’ya pas encore de calendrier.
  • LawnChair JavaScript wrapper http://brian.io/lawnchair/
    • PRO: wrapper très propre pour IndexedDB, WebSQL ou la base de données que vous possédez (pensez à polyfill)
    • CON: impossible de stocker des blobs binaires, uniquement des données: uri (encodage en base64) (probablement une erreur fatale en raison du coût du décodage)
  • IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
    • Parashuram a écrit un wrapper JQUERY Nice pour l'interface IndexedDB brute
    • PRO: simplifie grandement l’utilisation de IndexedDB, j’espérais ajouter un shim/polyfill pour Chrome FileSystemAPI
    • CON: Il devrait gérer les blobs, mais j'étais incapable de le faire fonctionner
  • idb.filesystem.js http://ericbidelman.tumblr.com/post/21649963613/idb-filesystem-js-bringing-the -html5-filesystem-api
    • Eric Bidelman @ Google a écrit une API bien testée de PolyFill, FileSystem, qui utilise la base de données indexée comme solution de secours.
    • PRO: L'API FileSystem est bien adaptée au stockage de blobs
    • PRO: fonctionne très bien sur Firefox et Chrome
      • PRO: idéal pour la synchronisation avec CouchDB basé sur le cloud
    • CON: pas clair pourquoi, mais ça ne marche pas sur IE10
  • PouchDB Bibliothèque JavaScript http://pouchdb.com/
    • idéal pour synchroniser un CouchDB avec une base de données locale (utilise WebSQL ou IndexedDB (pas mon problème cependant)
    • CON: NO CONS, PouchDB supporte maintenant les blobs binaires pour tous les navigateurs récents (IE, Chrome, Firefox, Chrome sur mobile, etc.) ainsi que de nombreux navigateurs plus anciens. Ce n'était pas le cas quand J'ai d'abord fait ce post.

NOTE: pour voir une donnée: encodage uri de PNG, j'ai créé un exemple à l'adresse: http://jsbin.com/ivefak/1/edit

Fonctionnalités souhaitées/utiles/inutiles

  • Aucune application native (EXE, PhoneGap, ObjectiveC, etc.) sur le client (application Web pure)
  • Ne nécessite que les derniers Chrome, FireFox et IE10 pour ordinateurs portables
  • Nous souhaitons vivement la même solution pour Android Tablet (IOS serait également agréable)), mais un seul navigateur suffit pour fonctionner (FF, Chrome, etc.)
  • Population de base de données initiale rapide
  • EXIGENCE: Récupération très rapide des images par application Web depuis le stockage (base de données, fichier)
  • Non destiné aux consommateurs. Nous pouvons restreindre les navigateurs et demander à l’utilisateur de faire une configuration et des tâches spéciales, mais minimisons cela.

Implémentations IndexedDB

  • Il existe un excellent article sur la manière dont IE, FF et Chrome implémentent cela en interne à: http://www.aaron-powell.com/web/indexeddb-storage =
  • En bref:
    • Internet Explorer utilise le même format de base de données que Exchange et Active Directory pour IndexedDB.
    • Firefox utilise SQLite donc implémente une base de données NoSQL dans une base de données SQL
    • Chrome (et WebKit) utilisent un magasin Key/Value qui possède un héritage dans BigTable

Mes résultats actuels

  • J'ai choisi d'utiliser une approche IndexedDB (et polyfill avec FileSystemAPI pour Chrome jusqu'à ce que le support blob soit fourni)
  • Pour aller chercher les tuiles, j’avais un dilemme puisque les gens de JQUERY cherchent à ajouter ceci à AJAX
  • Je suis allé avec XHR2-Lib de Phil Parsons, qui ressemble beaucoup à JQUERY .ajax () https://github.com/p-m-p/xhr2-lib
  • Performances pour les téléchargements de 100 Mo (IE10 4, Chrome 6, FireFox 7)).
  • Je ne pouvais obtenir aucune des enveloppes IndexedDB pour travailler avec des blobs (lawnchair, PouchDB, jquery-indexeddb, etc.)
  • J'ai roulé mon propre wrapper, et la performance est (IE10 2s, Chrome 3s, FireFox 10s)
  • Avec FF, je suppose que nous constatons un problème de performances lié à l’utilisation d’une base de données relationnelle (sqllite) pour un stockage non-sql.
  • REMARQUE, Chrome dispose d’outils de débogage exceptionnels (onglet développeur, ressources) pour inspecter l’état de IndexedDB.

FINAL Résultats affichés ci-dessous comme réponse

Mise à jour

PouchDB prend désormais en charge les blobs binaires pour tous les navigateurs récents (IE, Chrome, Firefox, Chrome sur mobile, etc.) ainsi que pour de nombreux navigateurs plus anciens. Ce n'était pas le cas lorsque j'ai publié ce message pour la première fois. .

103
Dr.YSG

Résultats Cache de blob hors ligne pour les cartes glissantes PNG

Test

  • 171 fichiers PNG (total de 3,2 Mo)
  • Plateformes testées: Chrome v24, FireFox 18, IE 10
  • Devrait également fonctionner avec Chrome & FF pour Android

Récupération depuis le serveur Web

  • utilisation de XHR2 (pris en charge sur presque tous les navigateurs) pour le téléchargement de blob depuis un serveur Web
  • Je suis allé avec XHR2-Lib de Phil Parsons, qui ressemble beaucoup à JQUERY .ajax ()

Stockage

Afficher

  • J'utilise Leaflet http://leafletjs.com/ pour afficher les carreaux de la carte.
  • J'ai utilisé le plug-in de couche de tuiles fonctionnelle d'Ishmael Smyrnow pour récupérer la couche de tuiles dans la base de données
  • J'ai comparé la couche de tuiles basée sur DB avec un stockage purement local (localhost: //)
  • Il n'y a pas de différence notable dans les performances! entre l'utilisation de IndexedDB et des fichiers locaux!

Résultats

  • Chrome: Fetch (6.551s), Store (8.247s), Temps total écoulé: (13.714s)
  • FireFox: Fetch (0.422s), Store (31.519s), Temps total écoulé: (32.836s)
  • IE 10: chercher (0.668s), magasin: (0.896s), temps total écoulé: (3.758s)
24
Dr.YSG

Pour vos besoins, je suggère de développer un nouveau polyfill basé sur deux autres: FileSystem API to IndexedDB et IndexedDB to WebSQL - est la meilleure option.

Le premier permettra de prendre en charge le stockage des blobs dans Chrome (API FileSystem)) et Firefox (IndexedDB), tandis que le second devrait fournir le support pour Android et iOS ( WebSQL ). Ce qu'il faut, c'est simplement que ces polyfill fonctionnent ensemble et je suppose que ce n'est pas difficile.

NB: Etant donné que je n'ai trouvé aucune information à ce sujet sur le Web, vous devez vérifier si le stockage des blobs à l'aide de la fonction WebSQL Polyfill fonctionnera sur iOS et Android. . Il semble que cela devrait fonctionner si:

var sql = ["CREATE TABLE", idbModules.util.quote(storeName), "(key BLOB", createOptions.autoIncrement ? ", inc INTEGER PRIMARY KEY AUTOINCREMENT" : "PRIMARY KEY", ", value BLOB)"].join(" ")

Source

4
Bogdan Kulynych

Il y a quelques années (pas exactement l'âge de pierre), j'utilisais une applet signée Java qui interrogeait son serveur pour connaître les exigences de synchronisation/mise à jour, téléchargeait les fichiers appropriés à partir du serveur et les sauvegardait sur le serveur). système de fichiers de l'utilisateur (pas une base de données). Cette solution peut fonctionner pour vous, bien que vous ayez besoin de quelqu'un pour écrire et signer l'applet. Pour les solutions de base de données, un tel applet peut utiliser le jdbc disponible pour la plupart des bases de données en utilisant localhost sur un port approprié ( Par exemple, 3306 pour MySQL). Je crois que la balise applet est obsolète en HTML 5 mais cela fonctionne toujours. Aucune expérience sur les tablettes Android, il est donc impossible de commenter cette partie-là.

1
Manidip Sengupta

J'ai la mise en cache de la carte exemples (exemple ouvert, découverte des régions et des zooms, commutation hors ligne et découverte des régions disponibles).

Il y a map.js - couche de la carte pour les tuiles hors ligne, storage.js - implémentation de stockage basée sur IndexedDb et WebSQL (mais cela ne fait que tester l’implémentation avec des performances médiocres).

  • Pour les fichiers de site (html, css, js, etc.), je préfère utiliser le cache d'applications.
  • Pour le stockage, je préfère utiliser la base de données indexée (blob de support), Web SQL (uniquement en base64), FileWriter (blob de support, mais uniquement en chrome). Franchement, le stockage est un gros problème pour cela. Vous avez besoin de la solution de clé la plus rapide qui les mélangera tous. Je pense que c'est une bonne décision d'utiliser la solution existante.
  • Pour aller chercher, j'ai utilisé canvas avec CORS. Mais je pense à WebWorkers et à XHR2 et cela peut être mieux à la place canvas car canvas pose quelques problèmes avec CORS dans différents navigateurs et autres (par exemple ce titre a été stocké mauvais à l'opéra ).

Informations complémentaires sur les tailles pour 2 milliards de villes ( Minsk ):

  • Zoom - 9, tuiles - 2, taille - 52 kb, avec le précédent - 52 kb;
  • Zoom - 10, tuiles - 3, taille - 72 kb, avec précédent - 124 kb;
  • Zoom - 11, tuiles - 7, taille - 204 kb, avec le précédent - 328 kb;
  • Zoom - 12, tuiles - 17, taille - 348 kb, avec précédent - 676 ​​kb;
  • Zoom - 13, tuiles - 48, taille - 820 Ko, avec précédent - 1,5 Mo;
  • Zoom - 14, tuiles - 158, taille - 2,2 mb, avec précédent - 3,7 mb;
  • Zoom - 15, tuiles - 586, taille - 5,5 mb, avec précédent - 9,3 mb;
  • Zoom - 16, tuiles - 2264, taille - 15 mb, avec précédent - 24,3 mb;
0
tbicr