オフラインWebアプリケーションの画像データの保存(クライアント側のストレージデータベース)


105

appcachingを使用したオフラインWebアプリケーションがあります。主にPNG画像ファイルで構成される(クライアント側で)保存する約10MB-20MBのデータを提供する必要があります。操作は次のとおりです。

  1. Webアプリケーションをダウンロードしてappcacheにインストール(マニフェストを使用)
  2. サーバーPNGデータファイルからのWebアプリリクエスト(方法?-以下の代替案を参照)
  3. 時々、Webアプリがサーバーと再同期し、PNGデータベースへの小さな部分的な更新/削除/追加を行います
  4. 参考:サーバーはJSON RESTサーバーであり、ピックアップのためにwwwrootにファイルを配置できます

これが、バイナリBLOBストレージを処理するクライアントベースの「データベース」の私の現在の分析です

下の更新を見る

  • AppCache(マニフェストを介してすべてのPNGを追加し、オンデマンドで更新します)
    • CON:PNGデータベースアイテムの変更は、マニフェスト内のすべてのアイテムの完全なダウンロードを意味します(本当に悪いニュースです!)
  • WebStorage
  • PhoneGapとSQLLite
    • CON:スポンサーは、認定を必要とするネイティブアプリとしてそれを拒否します
  • ZIPファイル
    • サーバーはzipファイルを作成してwwwrootに配置し、クライアントに通知します
    • ユーザーは手動で解凍し(少なくともそれが私の見方です)、クライアントファイルシステムに保存する必要があります
    • WebアプリはFileSystem APIを使用してファイルを参照します
    • CON:ZIPが大きすぎる(zip64?)、作成に時間がかかる
    • CON:FileSystem APIが常にサンドボックスから読み込めるかどうかわからない(そう思います)
  • USBまたはSDカード(石器時代に戻る...)
    • ユーザーはオフラインになる前にサーバーに対してローカルになります
    • SDカードを挿入し、サーバーにPNGファイルを挿入させます。
    • 次に、ユーザーはそれをラップトップ、タブレットに接続します
    • WebアプリはFileSystem APIを使用してファイルを読み取ります
    • CON:FileSystem APIが常にサンドボックスから読み込めるかどうかわからない(そう思います)
  • WebSQL
    • CON:w3cがそれを放棄した(かなり悪い)
    • IndexedDBとWebSQLをフォールバックとして使用するJavaScriptラッパーを検討するかもしれません
  • FileSystem API
    • Chromeはblobの読み取り/書き込みをサポートします
    • CON:IEとFireFoxについて明確でない(IE10、非標準のmsSaveがある)
    • caniuse.comはIOSとAndroidのサポートを報告しています(ただし、これはJSONのr / wだけですか、それとも書き込み用の完全なblob APIが含まれていますか?
    • CON:FireFoxの人々はFileSystem APIを嫌い、ブロブの保存をサポートしているかどうかは不明です:https : //hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
    • PRO:jsperf http://jsperf.com/indexeddb-vs-localstorage/15(ページ2)によると、BlobのIndexedDBよりはるかに高速
  • IndexedDB
    • IE10、FireFox(保存、ブロブの読み取り)での優れたサポート
    • ファイルシステムよりも高速で管理が容易(削除、更新)
    • PRO:速度テストを参照してください:http : //jsperf.com/indexeddb-vs-localstorage/15
    • IndexedDBでの画像の保存と表示に関するこの記事を参照してください:https : //hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
    • CON:Chromeがblob書き込みをまだサポートしていないことを確認しました(現在のバグですが、いつ修正されるかは明確ではありません)。
    • 更新:Chrome開発者は、デスクトップとAndroidの両方でこれに取り組んでいることを確認します!まだタイムラインはありません。
  • LawnChair JavaScriptラッパーhttp://brian.io/lawnchair/
    • PRO:IndexedDB、WebSQL、またはお持ちのあらゆるデータベースの非常にクリーンなラッパー(ポリフィルと考えてください)
    • CON:バイナリblobを保存できません。data:uri(base64エンコーディング)のみを格納します(デエンコーディングのコストのため、おそらく致命的な欠陥です)
  • IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
    • Parashuramは、生のIndexedDBインターフェース用の素晴らしいJQUERYラッパーを作成しました。
    • PRO:IndexedDBを使用して大幅に簡素化しました。ChromeFileSystemAPIにシム/ポリフィルを追加したいと考えていました
    • CON:blobを処理する必要がありますが、機能させることができませんでした
  • idb.filesystem.js http://ericbidelman.tumblr.com/post/21649963613/idb-filesystem-js-bringing-the-html5-filesystem-api
    • Eric Bidelman @ Googleは、フォールバックとしてIndexed DBを使用する十分にテストされたPolyFill FileSystem APIを作成しました
    • PRO:FileSystem APIはblobの保存に適しています
    • PRO:FireFoxとChromeでうまく機能します
      • PRO:クラウドベースのCouchDBとの同期に最適
    • CON:理由は明らかではありませんが、IE10では機能していません
  • PouchDB JavaScriptライブラリhttp://pouchdb.com/
    • CouchDBをローカルDBと同期するのに最適(WebSQLまたはIndexedDBを使用します(ただし、私の問題ではありません))
    • 短所:短所なし、PouchDBは最近のすべてのブラウザー(IE、Chrome、Firefox、モバイルのChromeなど)だけでなく、多くの古いブラウザーのバイナリBLOBをサポートするようになりました。私がこの記事を最初に書いたときはそうではありませんでした。

注:PNGのdata:uriエンコーディングを確認するには、http//jsbin.com/ivefak/1/editで例を作成しました

望ましい/便利な/必要な機能

  • クライアント(純粋なWebアプリケーション)にネイティブ(EXE、PhoneGap、ObjectiveCなど)アプリがない
  • ラップトップ用の最新のChrome、FireFox、IE10でのみ実行する必要があります
  • Androidタブレット用の同じソリューションが強く必要です(IOSもいいでしょう)が動作するために必要なブラウザーは1つだけ(FF、Chromeなど)
  • 迅速な初期DBポピュレーション
  • 要件:ストレージ(DB、ファイル)からのWebアプリケーションによる画像の非常に高速な取得
  • 消費者向けではありません。ブラウザーを制限し、ユーザーに特別なセットアップとタスクを実行するよう依頼できますが、それを最小限にしましょう

IndexedDBの実装

  • IE、FF、およびChromeがこれを内部でどのように実装するかについての優れた記事がありますhttp : //www.aaron-powell.com/web/indexeddb-storage
  • 要するに:
    • IEは、ExchangeおよびActive Directoryと同じデータベース形式をIndexedDBに使用します
    • FirefoxはSQLiteを使用しているため、SQLデータベースにNoSQLデータベースを実装するようなものです
    • Chrome(およびWebKit)は、BigTableに継承されているKey / Valueストアを使用しています

私の現在の結果

  • 私はIndexedDBアプローチを使用することを選択しました(そして、ブロブサポートが出荷されるまでChromeのFileSystemAPIでポリフィルします)
  • タイルを取得するために、JQUERYの人々がこれをAJAXに追加することについて熟慮しているので、私にはジレンマがありました
  • Phil ParsonsによるXHR2-Libを使用しました。これは、JQUERY .ajax()と非常によく似ています。https://github.com/pmp/xhr2-lib
  • 100MBダウンロードのパフォーマンス(IE10 4s、Chrome 6s、FireFox 7s)。
  • IndexedDBラッパーをblob(lawnchair、PouchDB、jquery-indexeddbなど)で機能させることができませんでした。
  • 私は自分のラッパーを転がし、パフォーマンスは(IE10 2s、Chrome 3s、FireFox 10s)です
  • FFでは、非SQLストレージにリレーショナルDB(sqllite)を使用することでパフォーマンスの問題が発生していると思います
  • 注:Chromeには、IndexedDBの状態を検査するための優れたデバッグツール(開発者タブ、リソース)があります。

回答として以下に掲載された最終結果

更新

PouchDBは、最近のすべてのブラウザー(IE、Chrome、Firefox、モバイルのChromeなど)および多くの古いブラウザーのバイナリBLOBをサポートするようになりました。私がこの記事を最初に書いたときはそうではありませんでした。


1
webstorageはjsonではなくstringをサポートしているため、imagezをbase64エンコードしてdataurlsとして提供できます。
mpm

わかりましたが、おそらく20MBの画像には最適ではない(またはクォータ内ではありません)。これは実際には滑りやすいマップタイルであり、ズームおよびパンするときにLEAFLETマップアプリケーションによって迅速にフェッチおよび表示する必要があります。
Dr.YSG

あなたが行った研究は非常に役に立ちます。
ボグダンクリニッチ2013年

私のポイントは、PNG画像を使用している場合は、バイナリBLOBを処理する必要がないことです。
MPM

正解です。入力内容を反映するようにドキュメントを更新してもよろしいですか?
Dr.YSG

回答:


25

PNGスリッピーマップのオフラインブロブキャッシュの結果

テスト中

  • 171 PNGファイル(合計3.2MB)
  • テストしたプラットフォーム:Chrome v24、FireFox 18、IE 10
  • Android向けChromeとFFでも動作するはずです。

ウェブサーバーから取得

  • WebサーバーからのblobダウンロードにXHR2(ほとんどすべてのブラウザーでサポート)を使用
  • Phil ParsonsのXHR2-Libを使用しました。これはJQUERY .ajax()に非常によく似ています。

ストレージ

表示

  • Leaflet http://leafletjs.com/を使用してマップタイルを表示しています
  • DBからタイルレイヤーを取得するためにIshmael Smyrnowによる機能タイルレイヤープラグインを使用しました
  • DBベースのタイルレイヤーを純粋にローカルな(localhost://)ストレージと比較しました
  • 性能に目立った違いはありません!IndexedDBとローカルファイルの使用の間

結果

  • Chrome:フェッチ(6.551秒)、ストア(8.247秒)、合計経過時間:(13.714秒)
  • FireFox:フェッチ(0.422秒)、ストア(31.519秒)、合計経過時間:(32.836秒)
  • IE 10:フェッチ(0.668秒)、ストア:(0.896秒)、合計経過時間:(3.758秒)

4

あなたの要件については、他の2つに基づいて新しいポリフィルを開発することをお勧めします。FileSystemAPI からIndexedDBへ、およびIndexedDBからWebSQLへ —が最良のオプションです。

前者はChrome(FileSystem API)とFirefox(IndexedDB)にblobを格納するためのサポートを有効にしますが、後者はAndroidとiOS(WebSQL)のサポートを提供するはずです。必要なのは、これらのポリフィルを一緒に機能させることだけで、難しいことではないでしょう。

注:これに関する情報をウェブ上で見つけることができなかったので、WebSQLポリフィルを使用してblobを保存することがiOSおよびAndroidで機能するかどうかをテストする必要があります。それはうまくいくはずです:

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

ソース


私はあなたの提案に傾いていますが、他の人からの連絡を待っています。私は便利なアンドロイドを持っていませんが、jsBinまたはjsFiddleを作成して、Androidで何が機能するかを確認することをお勧めします。
Dr.YSG

1
これら2つのblobは異なります。Sqlite blobはJavaScriptのarraybufferですが、js blobにはsqliteに相当するものはありません。Blobはarraybufferに変換できませんが、構造的に複製できます。
Kyaw Tun

2

私はマップキャッシュのを持っています(開いた例、領域とズームの検出、オフラインへの切り替え、および検出された領域が利用可能になります)。

map.jsオフラインタイルのマップレイヤーがありますstorage.js。IndexedDbとWebSQLに基づくストレージ実装です(ただし、これはパフォーマンスの低い実装をテストするだけです)。

  • サイトファイル(html、css、jsなど)の場合は、アプリケーションキャッシュを使用することをお勧めします。
  • ストレージには、インデックス付きDB(BLOBをサポート)、Web SQL(base64のみ)、FileWriter(BLOBをサポートしますが、Chromeのみ)を使用することをお勧めします。率直に言って、ストレージはこのための大きな問題です。それらをすべて組み合わせる最速のキーバリューソリューションが必要です。既存のソリューションを使用するのは良い決断だと思います。
  • フェッチにはCORSでキャンバスを使用しました。キャンバスは、(例えば異なるブラウザや他にCORSといくつかのトラブルを持っているので、しかし、私のWebWorkersについての考え方やXHR2、これは改善することができますではなく、キャンバス、このタイトルが格納されていたオペラで悪いが)。

20億都市(ミンスク)のサイズに関する追加情報:

  • ズーム-9、タイル-2、サイズ-52 kb、前-52 kb;
  • ズーム-10、タイル-3、サイズ-72 kb、前-124 kb;
  • ズーム-11、タイル-7、サイズ-204 kb、前-328 kb;
  • ズーム-12、タイル-17、サイズ-348 kb、前-676 kb;
  • ズーム-13、タイル-48、サイズ-820 kb、前-1.5 mb;
  • ズーム-14、タイル-158、サイズ-2.2 mb、前-3.7 mb;
  • ズーム-15、タイル-586、サイズ-5.5 mb、以前-9.3 mb;
  • ズーム-16、タイル-2264、サイズ-15 mb、前-24.3 mb;

私はそれらが滑りやすいEGPS3857形式のJPGタイルであると思いますか?私はリーフレットを使用していて、ラスタovelaysを行っているので、PNGを使用する必要がありました。また、PouchDB(下のIDBを使用)の使用のデモも確認してください。stackoverflow.com/questions/16721312/...
Dr.YSG

ああ、はい、その場でキャッシュしていますが、事前に構築されたOSMマップ(ワールドワイド)をズーム10または11または12に取得するためにどこに行くことができるか知っていますか?これをオフラインサーバーに保存します。
Dr.YSG 2013年

いいえ、PNGデフォルトのプロジェクション(EGPS:3857)で使用されていますが、タグまたはで使用されているJPEGかどうかは関係ありません。私の例では、(格納されている各タイルの)タイルキーがわかっている場合はタイルをプリロードできますが、境界(ポリゴン)とズームだけがわかっている場合は常にそれらを取得できます。PNGimgcanvasstorage.add('x_y_z', 'data:image/png;base64,...')
tbicr 2013年

言語の問題がないことを確認したいと思います。世界中のOSMの滑りやすいタイル(PNGまたはJPG)をズームレベル10に設定できる場所はありますか?
Dr.YSG 2013年

タイルフォームを取得できますtile.osm.org(mapnikレンダラー)。たとえばhttp://tile.openstreetmap.org/10/590/329.pngzoom/ x/ y.png)。このタイルにはAccess-Control-Allow-Origin: *ヘッダーがあるため、ajaxで取得したり、キャンバスでデータuri(base64)を取得したりできます。あなたはすでにあなたにタイルをダウンロードすることができますmanifest.json {id: 0-0-0}が、あなたは右の持っていることを確認しなければならないzoomxyシーケンス。
tbicr 2013年

1

数年前(厳密には石器時代ではありません)に、サーバーに同期/更新の要件を照会し、サーバーから適切なファイルをダウンロードして、ユーザーのファイルシステム(データベースではない)に保存する署名付きJavaアプレットを使用していました。アプレットを作成してそれに署名する人が必要になりますが、その解決策はうまくいくかもしれません。データベースソリューションの場合、このようなアプレットは、適切なポート(たとえば、MySQLの場合は3306)でlocalhostを使用して、ほとんどのデータベースで使用可能なjdbcを使用できます。Html5ではアプレットタグが廃止されたと思いますが、それでも機能します。Androidタブレットでは経験がないため、その部分についてはコメントできません。


1
私は1968年にカードパンチを使用してFORTRANでプログラミングを始めました。したがって、石器時代のソリューションは私にとって新しいものではありません。
Dr.YSG
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.