localStorageは最も基本的な機能のみを提供します。このストレージはかなり遅く、BLOBを保存できません。 IndexedDBとWebSQLは非同期で高速であり、大量のデータをサポートしますが、それらのAPIはかなり混乱します。 さらに、IndexedDBもWebSQLもすべての主要なブラウザでサポートされておらず、この状況は近い将来に変わらないようです。
オフラインモードでWebアプリケーションを作成する必要があり、どこから始めればよいかわからない場合は、これが最適です。 既にローカルリポジトリで作業を試みており、これで頭が一杯になった場合は、この記事も参考になります。 Mozillaでは、 localForageライブラリを作成しました。これにより、任意のブラウザーにローカルデータを保存するタスクが大幅に簡素化されます。
FoursquareのHTML5クライアントであるaroundの開発は、ローカルストレージでの作業のすべての困難を自分の肌で感じるのに役立ちました。 この記事ではlocalForageの使用方法について説明しますが、多分誰かがそれを使った実際の例を研究することを好むでしょう。
localForageは、 localStorage APIに似たAPIを使用する非常にシンプルなJavaScriptライブラリで、同じ基本的な
get
、
set
、
remove
、
clear
および
length
メソッドがありますが、その他の重要な改善点がいくつかあります。
- コールバックを使用した非同期API。
- IndexedDB、WebSQL、およびlocalStorageドライバー(ブラウザーの機能に応じて最適なドライバーが自動的に選択されます)。
- blobと任意のデータ形式のサポート。これにより、画像やファイルなどを保存できます。
- ECMAScript 6はサポートを約束します。
IndexedDBとWebSQLを使用すると、localStorageよりもはるかに多くのデータを保存できます。 非ブロッキング非同期APIは、アプリケーションのメインスレッドが
get/set
呼び出しの実行中にハングしないため、アプリケーションの高速化と応答性の向上を実現します。 promiseのサポートにより、コールバックからのスパゲッティなしでクリーンなコードを書くことができます。 もちろん、コールバックが好きなら、それらを使用できます。
話をやめて、それがどのように機能するか教えてください!
従来のlocalStorage APIは、多くの点で非常に優れています。 シンプルで、複雑なデータ構造を課すこともなく、定型的なコードもまったく必要ありません。 たとえば、アプリケーション構成をローカルに保存する必要がある場合、次のように記述できます。
// , var config = { fullName: document.getElementById('name').getAttribute('value'), userId: document.getElementById('id').getAttribute('value') }; // localStorage.setItem('config', JSON.stringify(config)); // var config = JSON.parse(localStorage.getItem('config'));
localStorageはすべての情報を文字列形式で保存するため、すべてをシリアル化されたJSONに変換する必要があることに注意してください。
すべてが非常にシンプルで論理的ですが、すぐにいくつかの問題に気付くことができます。
- 同期。 データのサイズに関係なく、データがディスクから読み取られ、パーサーによって処理されるまで待つ必要があります。 これにより、アプリケーションの応答性が低下します。 これは、モバイルデバイスでは特に悪いことです。メインデバイスは、データへのアクセス中に実行後にブロックされるため、アプリケーションが遅くなり、フリーズしているように見えます。
- すべてが文字列として保存されます。
JSON.parse
とJSON.stringify
を常に使用するJSON.parse
ありJSON.stringify
。 これは、localStorageがJavaScript文字列でのみ機能するためです。 数字、ブール値、ブロブなどはありません。 数値や配列を保存する必要がある場合、これは面倒です。また、バイナリデータを扱うと、ほとんど不可能になります(または少なくとも非常に遅くなります)。
localForageで生活を楽にする
localForageは、localStorageインターフェースに非常に似ているが非同期のAPIを使用して、これらの問題の両方を解決します。 IndexedDBの同等のコードよりも単純な方法を比較してください。
コードIndexedDB:
// IndexedDB. var db; var dbName = "dataspace"; var users = [ {id: 1, fullName: 'Matt'}, {id: 2, fullName: 'Bob'} ]; var request = indexedDB.open(dbName, 2); request.onerror = function(event) { // . }; request.onupgradeneeded = function(event) { db = event.target.result; var objectStore = db.createObjectStore("users", { keyPath: "id" }); objectStore.createIndex("fullName", "fullName", { unique: false }); objectStore.transaction.oncomplete = function(event) { var userObjectStore = db.transaction("users", "readwrite").objectStore("users"); } }; // , , var transaction = db.transaction(["users"], "readwrite"); // - transaction.oncomplete = function(event) { console.log("All done!"); }; transaction.onerror = function(event) { // }; var objectStore = transaction.objectStore("users"); for (var i in users) { var request = objectStore.add(users[i]); request.onsuccess = function(event) { // console.log(event.target.result); }; }
LocalForageコード:
// var users = [ {id: 1, fullName: 'Matt'}, {id: 2, fullName: 'Bob'} ]; localForage.setItem('users', users, function(result) { console.log(result); });
WebSQLを使用したコードは、IndexedDBを使用したコードよりも若干短くなりますが、localForageよりもはるかに多くのテキストが必要になります。
文字列だけでなく
ローカルで、またはユーザーに関するテキストデータだけでなく、ユーザーのアバターも使用するとします。 localForageを使用すると、これは非常に簡単に行われます。
// AJAX- var request = new XMLHttpRequest(); // , id=1 request.open('GET', "/users/1/profile_picture.jpg", true); request.responseType = 'arraybuffer'; // , request.addEventListener('readystatechange', function() { if (request.readyState === 4) { // readyState DONE // . localStorage localForage.setItem('user_1_photo', request.response, function() { // , . }); } }); request.send();
次の3行のコードを使用して、ストレージから写真を取得できます。
localForage.getItem('user_1_photo', function(photo) { // data URI - img. console.log(photo); });
コールバックと約束
コールバックが気に入らない場合は、ES6 promiseを使用できます。 これは、promiseを使用して書き換えると、最後の例のようになります。
localForage.getItem('user_1_photo').then(function(photo) { // data URI - img. console.log(photo); });
もちろん、これは人工的な例であり、あまり明白ではありません。 このスタイルのプログラミングを実際のコードで見たい場合は、ここに適切なスニペットがあります。
ブラウザー間の互換性
localForageは、すべての最新のブラウザーをサポートしています。 IndexedDB は 、Safari(IE 10 +、IE Mobile 10 +、Firefox 10 +、Android 25 +、Chrome 23 +、Chrome for Android 32 +、Opera 15+)を除くすべての最新ブラウザーで利用可能です。Safariおよび標準のAndroidブラウザー( 2.1+)WebSQLを使用します。
最悪のシナリオでは、localForageはlocalStorageを使用するため、blobがなくはるかに低速ですが、データをローカルに保存できます。 ただし、この場合、少なくともデータのJSON文字列への変換は自動的に行われます。
ライブラリはまだ非常に新しく、機能の一部が計画されているだけなので、開発に参加し、ライブラリにもっと多くのことができるようにしたい場合はエラーメッセージとパッチを送信してください!