iOSブラウザの localStorage
の検証をしてたら、思わぬ挙動に遭遇したのでまとめてみました。
検証結果から分かったのは、iOSのブラウザにて localStorage.setItem()
で保存した内容は、 メモリ上には同期処理ですぐに反映されますが、ハードディスクへの反映は非同期で行われているっぽい という事でした。
ハードディスクへの反映には時間が掛かるらしく、大量にデータを設定した後にすぐにブラウザアプリを落としてしまうと、保存したデータに抜けが発生してしまいます。
検証用サンプル
今回のサンプルでは、 setInterval()
を使って50ミリ秒ごとに複数回 localStorage.setItem()
を呼び出してデータを保存しています。
var PREFIX_KEY = "_";
var currentNum = 0; // 現在の番号
var incrementNum = 100; // 一度に保存する件数 (1 or 10 or 100)
setInterval(setItems, 50);
function setItems(){
var i;
for (i=0;i<incrementNum;i++) {
id = i + currentNum;
localStorage.setItem(PREFIX_KEY + id.toString(), "1"); // 値は常に"1"
if (id == 999) {
// 処理を打ち切り
}
}
}
localStorage.setItem()
で使用するキーは"_xxx"の形式になっていて、xxxの箇所は0から999までの範囲で合計1000件を保存できるようになっています。
また、1回の処理で保存できる件数は1、10、100から選べるようになっています。
検証結果
検証に使用した環境は以下の通りです。
・iPhone5 / iOS 7.1.1 / Safari
これを使用して100件ずつ保存してみます。
1000件分を保存するには10回呼び出す必要があるので、0.5秒程で呼び出し処理が完了します。
localStorageに1000件保存した結果
この時点で、 localStorage.length
はちゃんと1000になっています。
また、 localStorage.getItem()
を使って1個ずつ値をチェックしてみても、ちゃんと全てのキーに値が入っているようです。
アプリ再起動後
この後、すぐにSafariアプリを落として再起動します。
何故か localStorage.length
の値が400に減っていて、実際の中身も所々が抜けてしまっているようです。
一応、 length
の数と getItem()
でチェックした有効数は一致していました。
ちなみに、 今回の環境では約8秒待った後であれば1000件分のデータがちゃんと保持されている 事が確認取れています。
他に調べたこと
- iPhone3GS(iOS6.1.3)やiPad AIR(iOS7.1.1)でも同じような現象を確認
- SO-03D(Android 4.0)では起きてないっぽい
- 50ミリ秒に10件ずつの場合、再起動後に700件ぐらい保持
- 50ミリ秒に1件ずつの場合、再起動後でも確実に1000件保持
まとめ
この検証結果から考えると、一度にかなりの量のデータを保存しない限りは問題なさそうですが、データが抜けてしまう可能性があるのは要注意ですね。
ではでは。