[解決済み] オフラインのWebアプリケーションのための画像データの保存(クライアントサイドストレージデータベース)
質問
私は、appcaching を使用するオフラインの Web アプリケーションを持っています。私は、主に PNG 画像ファイルで構成される、保存される約 10MB ~ 20MB のデータを (クライアント側で) 提供する必要があります。操作は次のとおりです。
- Web アプリケーションがダウンロードし、appcache にインストールする (マニフェストを使用)
- Web アプリケーションがサーバーに PNG データ ファイルを要求する (どのように? - 以下の代替案を参照)
- 時折、Web アプリはサーバーと再同期し、PNG データベースの小さな部分的な更新/削除/追加を実行します。
- 参考: サーバーは JSON REST サーバーであり、ファイルを wwwroot に置いてピックアップすることができます。
以下は、バイナリ blob ストレージを扱うクライアントベースの "データベース" についての私の現在の分析です。
下部の更新を参照してください。
-
AppCache (マニフェストですべてのPNGを追加し、オンデマンドで更新する)
- CON: PNG データベース アイテムを変更すると、マニフェスト内のすべてのアイテムの完全なダウンロードを意味します (本当に悪いニュースです!)。
-
ウェブストレージ
- CON: JSON ストレージのために設計されています。
- CON: base64 エンコードによる blob のみの保存が可能 (エンコード解除のコストがかかるため、おそらく致命的な欠陥となる)
- CON: WebStorage の 5MB というハードリミットがある。 http://htmlui.com/blog/2011-08-23-5-obscure-facts-about-html5-localstorage.html
-
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 ラッパーを検討するかもしれない
-
ファイルシステムAPI
- Chrome は blob の読み込み/書き込みをサポートしています。
- CON: IE と FireFox については不明 (IE10 では、非標準の msSave がある)
- caniuse.com は IOS と Android のサポートを報告しています (しかし、これもまた、JSON の r/w だけなのか、それとも書き込み用の完全な blob API が含まれているのでしょうか?
- CON: FireFox の人々は FileSystem API & を嫌っている。彼らが Blob の保存をサポートしているかどうかは不明。 https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
- PRO: 多くの jsperf によれば、Blob を IndexedDB よりも高速に処理できる。 http://jsperf.com/indexeddb-vs-localstorage/15 (2ページ目)
-
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 の書き込みをサポートしていないことを確認しました (現在のバグですが、いつ修正されるかは不明です)
-
UPDATE
2014年6月のブログ記事
でChromeがBlobをサポートするようになったことを示唆しています。
IndexedDB
- UPDATE この caniuse/indexeddb は、"Chrome36以下では、indexedDBの値としてBlobオブジェクトをサポートしていなかったことを確認します。
-
ローンチェア JavaScript ラッパー http://brian.io/lawnchair/
- PRO: IndexedDB、WebSQL、またはあなたが持っているあらゆるデータベースのための非常にきれいなラッパー (ポリフィルを考えてください)
- CON: バイナリ blob を保存できず、data:uri (base64 エンコーディング) のみ (デエンコーディングのコストによる致命的な欠陥と思われる)
-
IndexedDB JQUERY ポリフィル https://github.com/axemclion/jquery-indexeddb
- Parashuram は、生の IndexedDB インターフェースのための素晴らしい JQUERY ラッパーを書きました。
- PRO: IndexedDB の使用を大幅に簡素化します。Chrome FileSystemAPI 用のシム/ポリフィルを追加することを望んでいました。
- 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 the FileSystem API を書きました。
- PRO: FileSystem API は blob を保存するのによく適している。
-
PRO: FireFox と Chrome で問題なく動作する。
- PRO:クラウドベースのCouchDBとの同期のために素晴らしい
-
PouchDB JavaScriptライブラリ http://pouchdb.com/
注:PNGのdata:uriエンコーディングを見るために、私は以下の例を作りました。 http://jsbin.com/ivefak/1/edit
必要な機能、便利な機能、不要な機能
- クライアント上にネイティブ (EXE、PhoneGap、ObjectiveC など) のアプリがない (純粋な Web アプリケーション)
- ラップトップでは最新の Chrome、FireFox、IE10 で実行する必要があります。
- Android タブレットにも同じソリューションを強く希望 (IOS も良い)、ただし動作するブラウザ (FF、Chrome など) のみ必要
- 高速な初期 DB 構成
- 要求事項 ストレージ(DB、ファイル)からのウェブアプリケーションによる画像の超高速検索
- コンシューマ向けではありません。ブラウザを制限したり、ユーザーに特別なセットアップやタスクを要求することはできますが、それは最小限にとどめましょう。
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 が blob サポートを出荷するまでは FileSystemAPI でポリフィルを行います)。
- タイルを取得するために、JQUERY の人々が AJAX にこれを追加することについて小言を言っているので、私はジレンマに陥りました。
- 私は Phil Parsons による XHR2-Lib を使用しました。これは JQUERY の .ajax() と非常によく似ています。 https://github.com/p-m-p/xhr2-lib
- 100MBダウンロード時のパフォーマンス(IE10 4s, Chrome 6s, FireFox 7s)。
- Blob に対して IndexedDB ラッパーのいずれかを動作させることができませんでした (lawnchair、PouchDB、jquery-indexeddb など)。
- 私は独自のラッパーをロールバックし、パフォーマンスは (IE10 2秒、Chrome 3秒、FireFox 10秒) です。
- FFの場合、非sqlのストレージにリレーショナルDB(sqllite)を使用した場合のパフォーマンスの問題が出ていると推測される
- 注: Chrome には、IndexedDB の状態を検査するための優れたデバッグ ツール (開発者タブ、リソース) があります。
FINALの結果を回答として以下に掲載します。
更新情報
PouchDBは現在、すべての最近のブラウザ(IE、Chrome、Firefox、モバイル上のChromeなど)だけでなく、多くの古いブラウザのためのバイナリブロブをサポートしています。私が最初にこの投稿を行ったときは、そうではありませんでした。
どのように解決するのですか?
結果 PNG スリッピーマップ用のオフライン blob キャッシュ
テスト
- 171 個の PNG ファイル (合計 3.2MB)
- テストしたプラットフォーム Chrome v24、FireFox 18、IE 10
- Android 版 Chrome & FF でも動作するはずです。
ウェブサーバから取得する
- Web サーバーからの blob のダウンロードに XHR2 (ほぼすべてのブラウザーでサポート) を使用する。
- 私は Phil Parsons 氏による XHR2-Lib を使用しました。これは JQUERY .ajax() に非常によく似ています。
ストレージ
- IE および FireFox 用の IndexedDB
- Chrome。Polyfill (BlobをFileSystem APIで保存し、IndexedDBで参照を保持する) polyfill
- ブラウザが IndexedDB データをどのように保存するかについての必読記事です"。
- 注意:FireFoxはNOSQL IndexedDBにSQLliteを使用しています。それがパフォーマンスの低下の原因かもしれません。(ブロブは別に保存されます)
- 注: Microsoft IE は、extensible storage エンジンを使用しています。
- 注:ChromeはLevelDBを使用 http://code.google.com/p/leveldb/
表示
- Leafletを使用しています。 http://leafletjs.com/ を使って地図タイルを表示しています。
- DBからタイルレイヤーを取得するために、Ishmael SmyrnowによるFunctional tile layer pluginを使用しました。
- DBベースのタイル層と純粋にローカル(localhost://)のストレージを比較したところ
- IndexedDBを使うのとローカルファイルを使うのとでは、パフォーマンスに顕著な差はありません!
結果
- Chrome。フェッチ (6.551s), ストア (8.247s), 経過時間合計: (13.714s)
- FireFox。フェッチ (0.422s), ストア (31.519s), 経過時間合計: (32.836s)
- IE 10。フェッチ (0.668s)、ストア。(0.896s), 経過時間合計: (3.758s)
関連
-
[解決済み] AngularJSのエラーです。Cross Origin リクエストはプロトコルスキーム http, data, chrome-extension, https に対してのみサポートされています。
-
[解決済み] ExtJS 4のイベントハンドリングについて
-
[解決済み] なぜ "use strict "はパフォーマンスを10倍向上させるのか?
-
[解決済み] アサインの左側にJavascriptのオブジェクトブラケット表記({ ナビゲーション } =)があります。
-
[解決済み] AngularJS - ngRepeatフィルタリングされた結果の参照を取得する方法
-
[解決済み] ECMAScriptとは?
-
[解決済み] Chromeのwebkitインスペクタで「Unsafe JavaScript attempt to access frame with URL...」というエラーが継続的に発生する。
-
[解決済み] Prototypeを使ってtextareaを自動サイズ調整するには?
-
[解決済み] 変異を伴わないオブジェクトからの値の削除
-
[解決済み] Fetch: ステータスがOKでない場合、プロミスを拒否し、エラーをキャッチするか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] JSのDateからDay名
-
[解決済み] ジェスト あるクラスの特定のメソッドをモックする方法
-
[解決済み] javascriptで2つの数値を連結する方法は?
-
[解決済み] 文字列のn番目の出現箇所を取得するには?
-
[解決済み] モバイルWeb HTML5フレームワークの選び方【終了しました
-
[解決済み] JavaScriptで、ある文字列が別の文字列の中に出現するすべてのインデックスを見つけるにはどうすればよいですか?
-
[解決済み] Javascript 空の配列の削減
-
[解決済み] 文字列とラベルのローカライズとグローバリゼーションのベストプラクティス【終了しました
-
[解決済み] jQueryを使用して、すべてのクリックイベントハンドラを削除するにはどうすればよいですか?
-
[解決済み] jQueryのバージョン1、バージョン2、バージョン3の違いは何ですか?[クローズド]