今時のウェブアプリのローカルストレージ事情

ウェブ系のストレージやクォータまわりのことをあんまり追ってなかったらけっこうかわっていたのでメモ。

そもそもは、 https://voice-memos.appspot.com/ というウェブアプリがあって録音ができるんだけど、で録音したデータはローカルに保存してるっぽいんだけど(IndexedDBを使っているっぽい)、どれぐらい長時間の音が録音できるんだろうか?ってのが気になったのだった。せいぜい数分なのか、それなりの時間でもオッケーなのか? というのは気になるところではないか?

ストレージ容量

クォータはnavigator.storage.estimate()という関数でとれる。ふつうにpromiseをかえすので、console.logなどしてみれば、てもとの端末だと(Chrome 64, Pixelbook)、

> navigator.storage.estimate().then(({quota}) => console.log(quota / 1024 / 1024 / 1024))
Promise {<pending>}
7.009137216955423

7GBくらい。意外とある。

ただ、実際にいろいろためしてみると(Chromeの場合)どのサイトにいっても同じ容量が提示される。もちろんそんなに無制限にストレージがつかえるわけがない。基本的にはこうしたデータは一時的なストレージであって、実際につかえるストレージを使いはたしそうになると問答無用に消されていく。

このへんの挙動やクォータ設定は、もちろんブラウザごとにいろいろちがう。https://developers.google.com/web/fundamentals/instant-and-offline/web-storage/offline-for-pwa に情報がまとめられているが、Chrome / Firefox はデバイスの残容量にもとづいてクォータを設定していて、ストレージを使いまくるとLRUでふるいデータを消していく。SafariとEdgeは消されないけどクォータはかなりすくないようにみえる。

さていきなり消されてしまうとこまるので、persistent storageとしてつかいたい、というリクエストを発行するAPIが用意されている。APIをよびだして許可されれば、つかったストレージはLRUにもとづいて消されたりせず永続化する。ただ許可といっても一般的なパーミッションAPIと(Chromeの場合は)ちがって、ユーザに許可をもとめるのではなく一定の条件で自動的に許可が降りるようになっている。詳しくは  https://developers.google.com/web/updates/2016/06/persistent-storage に記載がある。

ストレージの種類

かつていろんなストレージ系APIがあった。webSQLとか、filesystem APIとか、なんやかんや……。だいたいみんな消えた。現状、このへんはだいたい3種類に絞られてきているようだ。localStorage、CacheStorage、IndexedDBのみっつ。

localStorageとIndexedDBは前からあるけど、CacheStorage?っておもったのだが、service workersの文脈でよく登場するので誤解していたけれど、じつはふつうのブラウザ内のJSからもふつうに使える。ふつうのKVSとしても使える。IndexedDBとくらべるとだいぶ使うのがラクに思える。ただ、httpsでしかつかえないし、名前的にもフェッチ結果等のキャッシュにかぎって使ったほうがいいのだとおもう。swに保持してほしいデータをページからコントロールしたいときとかに使うべきなのだろう。

まあこのへんは直接さわるよりはなんかwrapしてくれるAPIを使うことのほうが多いんじゃないか、という気がするが。


そういうわけでもとの疑問に戻ると、当該ウェブアプリはストレージにIndexedDBを使っているので、Chromeとかであればわりとまともな時間でも保存できるようだ(iOS Safariだと無理かも)。ただpersistent storageは要求していないので、あんまり昔に録音したデータとかがいつのまにか消えている、てことはある。常識的な範囲内でつかえば意外とふつうにつかえそう。