2021年6月1日火曜日

2021年は IndexedDB 元年

Vocabee を作るに当たって初めて IndexedDB を触りました。 よくできてる。

IndexedDB でできるようになったこと

メモリ上の操作と比較するとさすがにデータ保存に若干のラグがあるので、 UIに影響のないように非同期で投げておき、コールドスリープ的な利用をする API になるかと思います。 IndexedDB ができたおかげで、ブラウザ上にいくらでも、気楽にデータを永続化できるようになりました。 ユーザ側でデータを溜めておいて、必要な時だけサーバにpushすればいい。 このとき小規模データならpushするサーバは自分で用意する必要がなく、 オンラインストレージなど色々な選択肢がある。 代替サービスがたくさんあるのでサービス停止リスクも今ならない。 仮にサーバを持つとしてもpushの頻度をいくらでも制御できる。 ようするに運用コストを思ったようにコントロールできるようになってきました。

2017年〜2019年 にオンラインストレージ API が揃った

私は 2020年に Photo Scanner というアプリを Dropbox 依存で作った時、オンラインストレージ依存は結構良いなあと思いました。 1年経って今度は Google Spreadsheet を使って Vocabee を作ってみて、やはり良いなあと感じました。 感触が良いのでこの実装方式っていつからできるようになったんだろうと思って調べてみると、案外最近です。

まず OAuth 2.0 の RFC は 2012年、Google OAuth 2.0 は 2016年 でした。 オンラインストレージサービスの対応は早く JavaScript SDK ができたのは、BOX, pCloud が 2016年、OneDrive や GoogleDrive が 2017年、Dropbox が 2019年でした。 データをオンラインストレージ任せにする発想自体は 2017年には現実的にはなっていたものの、有名企業が勢揃いしたのは 2019年。 他にも色々オンラインストレージサービスはありますが、いまのところ API で使えるのはこのへんかな。 ほどほどに新しい実装方法になるみたいです。

IndexedDB のスマホ対応は 2021 年

IndexedDB の仕様が固まったのは 2015年、デスクトップでサポートが安定したのは 2020年、 スマホでサポートが安定したのは 2021年と、こちらは予想以上に最近です。 このへんの事情は Can I use... の date relative のところを見るとよくわかります。 つまりレベルの高いデータプーリングができるようになったのは本当につい最近の話。 2021 年は IndexedDB 元年とも言える状態になっています。

スマホで高度なデータプーリングがしやすくなると何が起きるでしょうか。 私が真っ先に思い付いたのは先に語った通りで、フロントエンドでプーリングすることで負荷を下げやすくなる効果です。 OAuth でオフライン作業できなかったところを保持しておいて、後で投げるみたいな。 あとは私が作ったみたいに個人情報をすべて各自が管理できるところようになることだと思うんだよなあ。 個人開発だと個人情報なんか欲しくもないし集めたくもないのにサーバに保存しなきゃいけない事が多く、いつか爆発するかも知れないただの地雷、負債であることが多いです。 しかしOAuth 経由でユーザ自身に個人情報を保存させれば、そんなことに悩む必要がなくなります。 ほかにはゲームのセーブデータ管理かな。これもわざわざサーバに保存する必要性がなくなる。

何気に大きな変化になるかも

静的サービスは既に無料が基本になりつつありますが、小規模な write が発生する動的サービスも無料でいけるとわかりました。 これまでは小規模な write でも VPS やサーバーレスの DB が必要でした。 しかしオンラインストレージや Google Spreadsheet を利用すれば、今後は自前でサーバを持つ必要も、課金リスクのあるサーバーレスサービスも必要ありません。 サービス側もバックエンドで下手な負債を抱えずゼロリスクで構築でき、さらに無料放置できるため、より楽で現実的な実装と言えます。 個人レベルから中小企業程度のサービスなら運用コストをいくらでも減らせる、とても良い時代になりました。 逆に言えばバックエンド戦略はフロントエンドありきの時代とも言えますね。

使い勝手の所感

Vocabee を作って遊んでみた結論として、Google Spreadsheet は範囲を固定化したシーケンシャルな読み出しに強いですね。 OAuth で複雑なことをやるのはレスポンスに問題が出てきそうなので、アクセス回数は1-2回にしたい。 RDB のような最適化はせず、なるべく1回のアクセスでドカッと読み出して、後は計算するほうが処理も速度も早い。 シーケンシャルな処理で速度を保てるのは一般に〜数千件なので、そのへんを意識すると良さそう。 オンラインストレージも同じことが言えると思います。

OAuth は最初の判定に 1秒くらい掛かるので、データの読込はどうしても遅くなります。 一方、IndexedDB は openDB に 50〜100ms くらいしか掛かりません。 厳密なトランザクションを維持すると大変なことになるので、私は適当に非同期で書き込みし、同様に一定レベルだけ保って読み込みしてます。 読み込みする時は、ひとまず IndexedDB で読み込んで、非同期で後から内容を上書きするような利用が良いと思います。 ここでも厳密にやり過ぎると大変なので、多少の不整合は覚悟しながら、影響範囲を少なくする。 そして色々なタイミングで上書きしやすく、また不整合が起きにくいような実装にすると良さそう。 Google Spreadsheet はデータが存在しないとその列はスキップされる特性があるので、 だいたいのケースでは、オンラインストレージ側と IndexedDB 側の状態を管理する配列に書き込んでから DOM を更新するのが一番簡単。 DOM だけで処理しようとするとうまくいかない。

0 件のコメント: