112 votes

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

J'ai une application web hors ligne qui utilise appcaching. J'ai besoin de lui fournir environ 10 à 20 Mo de données à sauvegarder (côté client), principalement des fichiers d'images PNG. Le fonctionnement est le suivant :

  1. L'application web télécharge et installe dans appcache (utilise le manifeste)
  2. L'application web demande au serveur des fichiers de données PNG (comment ? - voir les alternatives ci-dessous)
  3. Occasionnellement, l'application web se resynchronise avec le serveur et effectue de petites mises à jour/suppressions/ajouts partiels dans la base de données PNG.
  4. FYI : Le serveur est un serveur JSON REST, qui peut placer des fichiers dans le wwwroot pour la collecte.

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

VOIR LA MISE À JOUR en bas de page

  • AppCache (via manifeste ajouter tous les PNG et ensuite mettre à jour à la demande)
    • CON : toute modification d'un élément de la base de données PNG entraînera le téléchargement complet de tous les éléments du manifeste (très mauvaise nouvelle !).
  • WebStorage
  • PhoneGap & SQLLite
    • CON : le sponsor la rejettera comme une application native nécessitant une certification
  • Fichier ZIP
    • Le serveur crée un fichier zip, le place dans le répertoire wwwroot, et informe le client.
    • l'utilisateur doit dézipper manuellement (du moins c'est comme ça que je le vois) et sauvegarder sur le système de fichiers du client.
    • L'application Web utilise l'API FileSystem pour référencer les fichiers.
    • CON : ZIP peut être trop grand (zip64 ?), temps de création long
    • CON : Pas sûr que l'API FileSystem puisse toujours lire en dehors du bac à sable (je pense que oui)
  • USB ou carte SD (retour à l'âge de pierre....)
    • L'utilisateur sera localisé sur le serveur avant d'être mis hors ligne.
    • On pourrait lui demander d'insérer une carte SD et laisser le serveur la remplir de fichiers PNG.
    • Ensuite, l'utilisateur le branchera sur l'ordinateur portable, la tablette
    • L'application Web utilisera l'API FileSystem pour lire les fichiers.
    • CON : Pas sûr que l'API FileSystem puisse toujours lire en dehors du bac à sable (je pense que oui)
  • WebSQL
    • CON : le w3c l'a abandonné (plutôt mauvais)
    • Je pourrais envisager un wrapper Javascript qui utilise IndexedDB et WebSQL comme solution de repli.
  • API pour les systèmes de fichiers
    • Chrome prend en charge la lecture/écriture de blobs
    • CON : pas clair pour IE et FireFox (IE10, a msSave non standard)
    • caniuse.com fait état d'une prise en charge d'IOS et d'Android (mais, là encore, s'agit-il simplement d'un r/w de JSON, ou inclut-il l'API blob complète pour l'écriture ?
    • CON : les gens de FireFox n'aiment pas l'API du système de fichiers et ne savent pas s'ils prennent en charge l'enregistrement des blobs : https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
    • PRO : Much plus rapide que IndexedDB pour les blobs selon jsperf http://jsperf.com/indexeddb-vs-localstorage/15 (page 2)
  • IndexedDB
    • Bon support dans IE10, FireFox (sauvegarde, lecture des blobs)
    • Bonne vitesse et gestion plus facile qu'un système de fichiers (suppressions, mises à jour)
    • PRO : voir les tests de vitesse : http://jsperf.com/indexeddb-vs-localstorage/15
    • Voir cet article sur le stockage et l'affichage des images dans IndexedDB : https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
    • CON : j'ai confirmé que Chrome ne prend pas encore en charge l'écriture de blob (bug actuel, mais on ne sait pas quand il sera corrigé)
    • MISE À JOUR : les développeurs de Chrome confirment qu'ils travaillent sur ce projet à la fois pour les ordinateurs de bureau et pour Android, mais pas encore de calendrier.
  • Chaise à gazon wrapper JavaScript http://brian.io/lawnchair/
    • PRO : enveloppe très propre pour IndexedDB, WebSQL ou toute autre base de données que vous avez (pensez au polyfill).
    • CON : ne peut pas stocker de blobs binaires, seulement data:uri (encodage base64) (probablement un défaut fatal dû au coût du désencodage)
  • IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
    • Parashuram a écrit un joli wrapper JQUERY pour l'interface brute d'IndexedDB.
    • PRO : simplifie grandement l'utilisation d'IndexedDB, j'espérais ajouter un shim/polyfill pour Chrome FileSystemAPI
    • CON : Il devrait gérer les blobs, mais je n'ai pas réussi à 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 un PolyFill the FileSystem API bien testé qui utilise Indexed DB comme solution de repli.
    • PRO : L'API du système de fichiers est bien adaptée au stockage des blobs.
    • PRO : fonctionne parfaitement sur FireFox et Chrome
      • PRO : excellent pour la synchronisation avec CouchDB basé sur le cloud
    • CON : pas de raison claire, mais cela ne fonctionne pas sur IE10
  • PouchDB Bibliothèque JavaScript http://pouchdb.com/
    • idéal pour synchroniser une base de données CouchDB avec une base de données locale (qui utilise soit WebSQL, soit IndexedDB, mais ce n'est pas mon problème).
    • CON : PAS DE 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 lorsque j'ai fait ce post pour la première fois.

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

Caractéristiques souhaitées/utiles/non nécessaires

  • Pas d'application native (EXE, PhoneGap, ObjectiveC, etc.) sur le client (application web pure).
  • Il suffit d'utiliser les dernières versions de Chrome, FireFox et IE10 pour les ordinateurs portables.
  • Je souhaite vivement que la même solution soit appliquée à la tablette Android (IOS serait bien aussi), mais il faut qu'un seul navigateur fonctionne (FF, Chrome, etc.).
  • Population initiale rapide des BD
  • REQUIS : Récupération très rapide des images par l'application web à partir du stockage (BD, 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 mettent en œuvre cette fonctionnalité en interne : http://www.aaron-powell.com/web/indexeddb-storage
  • En bref :
    • IE utilise le même format de base de données qu'Exchange et Active Directory pour IndexedDB
    • Firefox utilise SQLite, ce qui revient à implémenter une base de données NoSQL dans une base de données SQL.
    • Chrome (et WebKit) utilise un magasin de clés/valeurs dont l'héritage se trouve dans BigTable.

Mes résultats actuels

  • J'ai choisi d'utiliser une approche IndexedDB (et un polyfill avec FileSystemAPI pour Chrome jusqu'à ce qu'ils livrent le support des blobs).
  • Pour récupérer les tuiles, j'ai eu un dilemme puisque les gens de JQUERY se plaignent de l'ajout de cette fonctionnalité à AJAX.
  • J'ai choisi XHR2-Lib de Phil Parsons, qui ressemble beaucoup à JQUERY .ajax(). https://github.com/p-m-p/xhr2-lib
  • Performances pour des téléchargements de 100 Mo (IE10 4s, Chrome 6s, FireFox 7s).
  • Je n'ai pu faire fonctionner aucun des wrappers IndexedDB pour les blobs (lawnchair, PouchDB, jquery-indexeddb, etc.).
  • J'ai créé mon propre wrapper, et les performances sont les suivantes (IE10 2s, Chrome 3s, FireFox 10s)
  • Avec FF, je suppose que nous rencontrons le problème de performance lié à l'utilisation d'une base de données relationnelle (sqllite) pour un stockage non relationnel.
  • REMARQUE : Chrome dispose d'outils de débogage exceptionnels (onglet "développeur", ressources) pour inspecter l'état de l'IndexedDB.

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

Mise à jour

PouchDB supporte désormais 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 fait ce post pour la première fois.

27voto

Dr.YSG Points 843

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

Essais

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

Récupération depuis le serveur web

  • utilisation de XHR2 (supporté par presque tous les navigateurs) pour le téléchargement de blob à partir du serveur web
  • J'ai choisi XHR2-Lib de Phil Parsons, qui ressemble beaucoup à JQUERY .ajax().

Stockage

Afficher

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

Résultats

  • Chrome : Récupérer (6.551s), Stocker (8.247s), Temps total écoulé : (13.714s)
  • FireFox : Récupérer (0,422s), Stocker (31,519s), Temps total écoulé : (32,836s)
  • IE 10 : Fetch (0.668s), Store : (0.896s), Temps total écoulé : (3.758s)

5voto

Hidden Markov Points 423

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

Le premier permettra de prendre en charge le stockage des blobs dans Chrome (API de système de fichiers) et Firefox (IndexedDB), tandis que le second devrait assurer la prise en charge d'Android et d'iOS ( WebSQL ). Ce qu'il faut, c'est simplement faire fonctionner ces polyfills ensemble, et je suppose que ce n'est pas difficile.

NB : Comme je n'ai pas trouvé d'informations sur le web à ce sujet, vous devriez tester si le stockage de blobs à l'aide du polyfill WebSQL fonctionnera sur iOS et Android. Il semble que cela devrait fonctionner :

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

Source :

2voto

David Rousset Points 41

Ce fil de discussion est très intéressant et je me suis posé les mêmes questions ! J'ai fini par mettre en œuvre la solution que j'ai décrite ici : http://blogs.msdn.com/b/davrous/archive/2013/09/24/using-indexeddb-to-handle-your-3d-webgl-assets-sharing-feedbacks-amp-tips-of-babylon-js.aspx pour stocker les textures et les maillages 3D de notre moteur WebL 3D. Je fais référence à ce fil de stackoverflow dans cet article.

J'espère que cet article sera utile à certains d'entre vous et que Chrome prendra bientôt en charge le stockage des blobs dans IndexedDB. Je n'ai pas vraiment regardé les polyfills disponibles en utilisant l'API FileSystem. Quelqu'un a-t-il essayé de tels polyfills ?

Au revoir,

David

2voto

tbicr Points 4969

J'ai des exemples de mise en cache de cartes : https://github.com/tbicr/OfflineMap (ouvrir l'exemple, découvrir les régions et les zooms, passer hors ligne et les régions découvertes seront disponibles). Il existe map.js - couche de carte pour les tuiles hors ligne, storage.js - implémentation de stockage basée sur IndexedDb et WebSQL (mais ce n'est qu'une implémentation de test avec de faibles performances).

  • Pour les fichiers du site (html, css, js, etc.), je préfère utiliser le cache des applications.
  • Pour le stockage, je préfère utiliser Indexed DB (support blob), Web SQL (seulement base64), FileWriter (support blob, mais seulement chrome). Franchement, le stockage est un gros problème dans ce cas. Vous avez besoin de la solution clé-valeur la plus rapide qui puisse les mélanger toutes. Je pense que c'est une bonne décision d'utiliser la solution existante.
  • Pour l'extraction, j'ai utilisé canvas avec CORS. Mais j'ai pensé à WebWorkers et XHR2 et cela peut être mieux que canvas parce que canvas a quelques problèmes avec CORS dans différents navigateurs et autres (par exemple ce titre a été stocké mauvais dans l'opéra ).

Informations supplémentaires sur les tailles pour 2 milliards de ville ( Minsk ) :

  • Zoom - 9, tuiles - 2, taille - 52 kb, avec 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 précédent - 328 kb ;
  • Zoom - 12, tuiles - 17, taille - 348 kb, avec précédent - 676 kb ;
  • Zoom - 13, tuiles - 48, taille - 820 kb, avec précédent - 1.5 mb ;
  • Zoom - 14, tuiles - 158, taille - 2,2 mb, avec le 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 ;

1voto

Manidip Sengupta Points 1213

Il y a quelques années (pas exactement à l'âge de pierre), j'utilisais un applet java signé qui interrogeait son serveur pour connaître les besoins en matière de synchronisation/mise à jour, téléchargeait les fichiers appropriés depuis le serveur et les sauvegardait sur le système de fichiers de l'utilisateur (pas une base de données). Cette solution pourrait vous convenir, bien que vous ayez besoin de quelqu'un pour écrire l'applet et la signer. Pour les solutions de base de données, une telle 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 dépréciée dans Html5 mais elle fonctionne toujours. Je n'ai pas d'expérience avec les tablettes Android, donc je ne peux pas faire de commentaires sur cette partie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X