10 ポイント 投稿者 GN⁺ 2025-09-23 | 1件のコメント | WhatsAppで共有
  • ローカルファーストアプリ高速な応答性基本的なプライバシー保護を約束する一方で、実際にはオフライン対応の実装が非常に難しいという限界がある
  • 最大の理由は同期の複雑さにあり、複数のデバイスで同時にデータが変更された場合、最終的に完全に同一の状態へ収束しなければならないという問題が生じる
  • 大きな技術的課題は、時間順序の不確実性競合の2つである
  • この問題を解決するには、Hybrid Logical Clocks(HLCs)CRDTs のような分散システム設計を適用する必要がある
  • SQLite ベースの拡張機能を活用することで、信頼性が高くシンプルな同期アーキテクチャを提供でき、これはあらゆるプラットフォームで利用可能である

オフラインファーストアプリの約束と現実

  • オフラインファーストアプリは、即時の応答基本的なプライバシー保護不安定なネットワーク環境でも読み込み待ちなしで利用できることを掲げている
  • 実際には、ほとんどのアプリがオフライン対応を十分に実装できておらず、多くは変更をローカルに一時保存し、後でネットワーク接続時に送信する方式にとどまっている
  • このような実装は信頼性に欠け、最終的には「変更が保存されない可能性があります」といった警告メッセージにつながる

同期の根本的な難しさ

  • ローカルファーストアプリを作ると、必然的に分散システムを構築することになる
  • 複数のデバイスがオフライン環境でそれぞれ独立してデータを変更でき、後で再接続したときに同一の状態へ正確に収束しなければならない
  • そのためには2つの大きな課題が存在する
    • イベント順序の不確実性
    • 同一データに対する競合

1. イベント順序の不確実性

  • 複数のデバイスでイベントが異なる時点に発生し、順序によって状態が変わりうる
    • 例: Aデバイスは x=3 に設定、Bデバイスは x=5 に設定 → オフラインでそれぞれ変更した後に同期すると、異なる結果が生じる可能性がある
  • 従来の集中型データベースは強い一貫性によってこれを解決するが、これはグローバル同期を必要とするため、ローカルファーストシステムには適していない
  • 最終的には、イベントごとに適切な順序を動的かつ分散環境でも確定する必要があり、中央の時計なしで順序を決める方法が求められる

Hybrid Logical Clocks(HLCs)の導入

  • Hybrid Logical Clocks(HLCs) は、個々のデバイス間でイベント順序について実質的に合意できるようにする、シンプルで効果的なアルゴリズムである
  • HLCは物理時間情報と論理カウンタを組み合わせて利用する
  • 例として:
    • Aデバイスが 10:00:00.100 の時刻にイベントを記録した場合、HLCは (10:00:00.100, 0)
    • メッセージを受け取ったBデバイスは、自身の時計が遅れていても、HLCを (10:00:00.100, 1) に進める
    • これにより、2つのデバイスの物理時計の差に関係なく、正確なイベント順序を確定できる

2. 競合の問題

  • 正しい順序の適用だけでは十分ではなく、異なるデバイスで同じデータが独立して修正された場合、競合は必然的に発生する
  • ほとんどのシステムは、開発者に競合解決コードを手動で書かせるが、これはエラー発生のリスクと運用負担を招く

CRDTsの活用

  • Conflict-Free Replicated Data Types(CRDTs) を適用するのが最良の方法である
  • CRDTsは、どのような順序で同期しても、あるいは重複適用しても、各デバイスの状態が最終的に常に同一になることを保証する
  • 最も単純なCRDT戦略はLast-Write-Wins(LWW) である
    • 各更新にタイムスタンプを付与する
    • 同期時には、より新しいタイムスタンプの値が選ばれる

SQLiteの利点

  • ローカルファーストアプリを構築するには、信頼性が高く軽量なローカルDBが不可欠であり、SQLite が最適な選択肢である
  • SQLiteベースのフレームワーク拡張で同期機能を実装すると、次のような利点がある
    • メッセージ適用は単純: 現在値を参照 → 新しいタイムスタンプのほうが新しければ上書き → そうでなければ無視
    • この方式は同期順序に関係なく、全デバイスでの状態収束性を保証する

アーキテクチャの意義

  • この構造はシンプルで信頼性の高い同期を実現する
    • 数週間オフライン状態でもデータ消失がない信頼性
    • 常に最終状態へ収束する決定論的性質
    • 重い依存関係のない軽量なSQLite拡張だけで実現可能
    • iOS, Android, macOS, Windows, Linux, WASM など主要な全プラットフォームをサポート

開発者への提言

  • 単純なリクエストキューでオフラインモードを“それらしく”見せる方式は避けるべきである
  • 結果整合性の概念を受け入れ、HLCやCRDTのような実証済みの分散システム技術を活用する必要がある
  • 大きく複雑なフレームワークではなく、小さく依存関係の少ない構造を志向するのが望ましい
  • その結果、アプリは即時起動オフライン利用可能基本的なプライバシー保護といった利点を享受できる

オープンソース SQLite-Sync 参考案内

  • プロダクションで今すぐ使えるクロスプラットフォームのオフラインファーストエンジンに関心があるなら、オープンソースの SQLite-Sync 拡張を参照できる

1件のコメント

 
GN⁺ 2025-09-23
Hacker Newsの意見
  • CRDT(Conflict-Free Replicated Data Types)が解決策だと言われるが、実際には直感的なユーザーの期待と一貫したビジネスロジックに合うCRDTモデルを作るのは本当に難しく、データモデルをメッセージの塊に変えたうえで実際の状態へ継続的に再構成しなければならないため、とてつもない頭痛の種になる
    • 新しいWeb標準としてBRAIDというイニシアチブがある。これはWebの状態同期標準を目指し、運用変換(OT)とCRDT技術をHTTPに適用して、本質的に人間にも機械にもより親和的な同期Webを作ろうとするもの。Braidはネットワーク性能を高め、ネイティブP2P・協調編集・ローカルファーストなWebアプリ開発を支援する。関連リンクはBRAIDミーティングBraid HN議論RESTful API議論Braid HTTP解説
    • CRDTの話はまるで万能な解決策のように語られるが、実際には自動マージはそう簡単ではない。技術的には最後の書き込みが勝つアルゴリズムもCRDTと見なせるが、複雑なテキストマージでユーザーの意図と期待の両方を尊重しようとすると、ほとんど不可能に近い難題になる。しかも状況によっては、CRDTでマージを試みること自体がむしろ誤ったアプローチかもしれない。たとえば会議室予約で2人が同時に同じ部屋を予約した場合、アルゴリズムではなく、ユーザー自身が競合を認識して解決するべきだ
    • 気後れすると挑戦しにくい領域だという点には同意する。勇気のない人のための「CRDTなし」の代替案もあり、詳しくはこちらを参照
    • 私たちのチームはローカルファーストなアプリを作る際、競合状況をそのまま無視する方法を使っている。最後の変更が勝つ方式だ。ほとんどの競合は些細なものか(監査ログ程度で簡単に解決可能)、そもそも自動では解決できない場合が多い。たとえばオフライン対応のタスクトラッカーで2人が同時に同じ作業を始めるケースは、ビジネスプロセスとして別途処理すべきだ
  • 昔はほとんどすべてのソフトウェアがローカルファーストで、それが当たり前だった。だが最近は世界が全面的に統制と利益最適化で動いており、その結果、人々がより頻繁に不利益を被る構造になってしまっている。不満があっても代替手段が特にないからだ
    • 昔オンプレミスやセルフホスト製品を作っていた頃、最大の顧客不満はクラウドの選択肢がないことだった。ほとんどの企業はセルフホストを望まず、むしろ月額料金を払って他所に任せることを好む。クラウドサービス需要が実際には非常に大きい点を、HNは過小評価しているように思う
    • 「人々がもっと搾取されないサービスを望むなら、それで儲けられるはずだ」という主張は、経済学的には成り立たない。問題は、人々が実際にはある程度の不利益を受け入れていることだ。もし教育やリスク認識がもっと高まれば変わるかもしれないが、それは非常に解くのが難しい課題だと思う
    • 代案としてはFOSS(オープンソースソフトウェア)が考えられる
  • アプリがすべてのコンテンツをオンラインだけに依存しないでほしい。Tesla GPSも、すでに取得したタイルをキャッシュしないため、オフラインでは地図に何も表示されない。PeacockやKanopyのようなアプリも、メディア一覧やレンダリング済みオブジェクト自体を端末に残さない。端末にはすでに95%のコンテンツがあるのだから、それを積極的に活用してほしい。UIをdirtyとして表示し、非同期保存の成功を待てばいい。オフラインアプリ設計に大きな変化を要求しなくても、よりよい習慣さえあれば大半の問題は簡単に解決できる
    • APIレスポンスでCache-Controlを正しく使い、ネットワーク層でそれを順守することで多くの問題を解決できる。こうすればサーバー側でキャッシュ寿命を変えても、アプリ更新なしですぐ適用できる
    • Google Mapsはオフラインマップを手動で範囲選択してダウンロードでき、複数エリアを同時にキャッシュすることも可能だ。国立公園を訪れたとき、オフラインでうまく使えた
    • 「アプリ設計を変えなくてもよい」という主張に対して、企業の目的は実際にはもっと多くのデータを集めることだと思う。たとえばAppleもオフラインマップを提供したが、意図的にデータを失効させてユーザーを自社に囲い込もうとしている。Tesla(あるいはGoogle)の地図タイルにも隠れた意図があるのではと推測する
  • アプリのローカルファースト性や分散性といった「政治的にホットな」話題に集中するあまり、人々が本当に望んでいる中核的価値を見失う例が多い
    • Immichへ移行して、セルフホストだから妥協することになると思っていたが、AppleやGoogleよりはるかに良くて驚いた。ユニコーンのように珍しい製品だ
  • ローカルファーストなアプリが人気でないのは、結局は経済的な問題だと思う。SaaSや広告ベースのモデルは確立している一方、ローカルファーストなアプリは収益性が著しく低い。このモデルを好む人たちは、データ主権、エンドツーエンド暗号化、オフライン利用など、既存の収益モデルと相反する特性を重視する。結局、オープンソースコミュニティの情熱に頼るしかない
    • もはや「金+データ」を払うか「広告視聴」しか選べず、本当の現金だけを払ってデータは守られるモデルは排除されているのが現実だ
    • 私もRelayというローカルファーストなアプリを作っていて、ObsidianにGoogle Docs風の協業機能を付けるものだ。ビジネスモデルは独特だと思う。サービスは「グローバルアイデンティティレイヤー」と「Relay Server」(オープンソース/セルフホスト可)に分かれており、ユーザーが文書内容を完全に制御できる。簡単なシングルサインオンと権限管理を提供し、AI・AI Safety分野の企業やコンプライアンスが重要な会社から特に関心を集めている。リンクはRelay.md
    • 私が周囲でよく見る現象は、購入時にサブスクリプションしか提示されず、結局買わない消費者だ。とりあえず買って後で使いたいのに、制限条件(割引期間、再訪時の値上げなど)のせいで、そもそも購買意欲が折れてしまう。これが最適なビジネスモデルだとは思えない
    • 問題はレプリケートされたデータ構造ではないと思う。シングルプレイヤーゲームのように完全にローカルファーストでも、ランチャー経由でインターネット接続を要求することが多い
    • ローカルファーストなアプリは複雑性の問題も深刻だ。あらゆるデバイス、環境で動くようにしなければならず、クラウドファーストなアプリはサーバー上の単一環境だけに合わせればよいので、相対的に簡単で維持費も少ない
  • かつてはデスクトップ・モバイルソフトウェアのほうがむしろ奇妙な例外のように扱われていたが、今でも非常に一般的なソフトウェア配布方式だ。一方でブラウザーでローカルファースト機能を実装しようとすると、ホストシステムとの連携問題など、ブラウザーの欠点ばかり背負い込むことになる
  • 何か見落としているのかもしれないが、一般的に「ローカルファースト」アプリはごく普通なのではないかと思う。大半のユーザーもオフライン前提のアプリを多く使っている。もし「ローカルファーストWebアプリ」のことなら、そのほうがまだ正確だろう。実際、「ローカルファーストWebアプリ」自体が矛盾したコンセプトだ
    • ほとんどのアプリが(直接料金を払って使う)ローカルファースト型なのか、むしろ問い直したい。ゲームを除けば、もはやそういう会社はほとんどない気がするし、シングルプレイゲームですらDRM、不正防止、アップデートなどを理由にインターネットを要求するのが現実だ
    • ここで言う「ローカルファースト」とは、クラウド保存ではなく、そもそもローカルデータを基本に据え、クラウドとの同期を支援するアプリを意味する
  • オフラインファーストなアプリでも、不安定なネットワーク接続ではローディングスピナーが回る点で大差ない。たとえばGoogle Docsは文書が最新か確認しようとして引っかかり、機内モードで強制的に切断して初めて即座に開く。Spotifyも保存済みプレイリストですら、オンラインの付加情報を取りに行こうとして止まる。結局、不安定な接続はオフラインアプリ開発における最大の頭痛の種だ。アプリは常にもう一度クラウドデータへアクセスしようとするからだ
  • 記事のソリューションもクローズドなクラウドオファリングに閉じている。Firebaseのようにそれ自体は悪くないが、その事実が明確に表示されず、「単なるsqlite拡張」といった表現の裏で商用クラウドしかサポートされていない点が残念だ。PowersyncやElectricSQLのようなベンダーは少なくともこの事実を透明に示しており、Powersyncはセルフホストも可能にしている
    • ローカルファーストの概念が開発者ツールに適用できるのか、少し迷う。SQLite-sync系のツールでローカル保存モデルベースのソフトウェアを作れるか、検討の必要を感じる。ElectricSQLはセルフホスト可能で、私の「sqlite sync」ツール一覧も更新し続ける必要がありそうだ。関連リンクはlocal-first原文SQLSyncSQLiteSyncSQLite-Sync
  • 私は、もっと多くのローカルオンリー、セルフホストのアプリが必要だと思う。あるいは連合型(Federated)構造でもよい。ネットワークインフラがこれまで障害だったと感じるが、Tailscaleのようなソリューションが登場したことで、この種のアプリは大きく作りやすくなるはずだ
    • プレゼンテーションソフトウェアを作っているのだが、ローカルで必ずしっかり動く必要がある一方、同時にどこからでもアクセス可能でなければならない。この両立が思った以上に難しい。しかし技術の進歩でdirect connectionやWebRTCなどのP2P実装は容易になりつつある。実際の製品に落とし込み、テストするのはまだ挑戦だ。それでも今後は、ローカルファーストでありながらネットワーキングにも優れたソフトウェアがますます増えると思う。オープンソースだ。詳しくはプロフィール参照
    • 私も最近この分野を面白く探っている。詳しい文章はこちらで読める。新しいやり方のアプリ構築はかなり楽しい