ローカルファースト・ソフトウェア:クラウド時代にも自分のデータを所有する(2019)
(inkandswitch.com)- クラウドアプリはコラボレーションとマルチデバイスでのアクセス性を大きく改善したが、権威あるデータのコピーがサーバーにあるため、ユーザーの所有権と制御権が弱まる
- ローカルファースト・ソフトウェアはノートPC・タブレット・スマートフォンのローカルストレージを主要なデータコピーとし、サーバーは同期・バックアップを支援する補助的な役割に限定する
- このアプローチは、高速な応答、オフライン作業、複数デバイス同期、リアルタイムコラボレーション、長期保存、デフォルトのセキュリティ・プライバシーを同時に追求する
- ファイル、メール、Webアプリ、Dropbox系の同期、Git、Firebase、CloudKit、Realm、CouchDBはそれぞれ一部の長所を持つが、コラボレーションとデータ所有権の両方を満たしてはいない
- CRDTとAutomergeベースのプロトタイプは可能性を示したが、性能、ネットワーク通信、P2Pの安定性、分散ドキュメントUIといった課題が残っている
クラウドでの協業とデータ所有権の衝突
- Google Docs、Figma、Slack、Trelloのようなクラウドアプリは、ブラウザやモバイルアプリからアクセスし、データをサーバーに保存する
- このモデルはリアルタイムコラボレーションとどこからでもアクセスできる利点を提供する一方、すべてのデータアクセスがサーバーを経由しなければならない
- サーバーが許可する操作しかできない
- サービスが停止すると、ソフトウェアだけでなく、そのソフトウェアで作成したデータへのアクセスも失われる可能性がある
- データをエクスポートできても、サーバーなしで同じソフトウェアを継続して実行するのは難しい
- これに対して、古いローカルアプリはローカルディスク上のファイルを読み書きするため、ユーザーがバックアップ、長期保存、他プログラムでの操作、削除を直接制御できる
- 核心的な緊張関係は、クラウドがコラボレーションを与え、ローカルアプリが所有権を与える点にあり、ローカルファーストはその両方を同時に得ようとする設計方針である
ローカルファースト・ソフトウェアの基本モデル
- ローカルファースト・ソフトウェアは、遠隔データセンターのサーバーよりもローカルストレージとローカルネットワークを優先する
- クラウドアプリでは、サーバー上のデータが権威ある原本であり、クライアント側のデータはサーバーに従属したキャッシュに近い
- ローカルファースト・アプリでは、各デバイスのローカルデータが主要なコピーであり、サーバーは複数デバイスからのアクセスとバックアップを支援する補助コピーを持つ
- この視点の転換は、性能、オフライン利用、長期保存、プライバシー、ユーザーの制御権に直接影響する
ローカルファーストの7つの理想
-
1. スピナーのない即時の操作
- クラウドアプリでは、データの変更や多くの参照にサーバーとの往復が必要なため、遅延が生じる
- Optimistic UIは、リクエストが完了したかのように見せて遅延を隠すが、ネットワークエラーが起きると再び遅延が表面化する
- ローカルファースト・アプリでは、主要データがローカルデバイスにあるため、ユーザー入力がサーバー応答を待つ必要が減る
- 同期はバックグラウンドで進み、アプリは入力にほぼ即時に反応できる
-
2. 1台のデバイスに閉じない作業
- ユーザーはスマートフォンでアイデアをキャプチャし、タブレットで整理し、ノートPCで文書化するといった形で複数のデバイスを行き来する
- ローカルファースト・アプリでも各デバイスにデータを置きつつ、すべての作業デバイス間での同期が必要になる
- ほとんどのデバイス間同期サービスは、サーバーにもコピーを保存してオフサイトバックアップの役割を果たす
- 複数人が同じファイルを同時に編集すると競合が発生し得るため、コラボレーション設計が重要になる
-
3. 任意であるネットワーク
- 飛行機、トンネル、エレベーター、駐車場、不安定なWiFi、ローミング費用、発展途上国や農村部の不完全なインターネット環境は、オフライン作業の必要性を生む
- クラウドアプリは一般にオフラインに弱く、サーバー中心モデルに後からオフライン対応を付け足すのも難しい
- ローカルファースト・アプリは各デバイスのローカルファイルシステムに主要データを保存するため、オフラインでも読み書きできる
- その後、ネットワークが利用可能になったときに他のデバイスと同期し、同期はインターネットだけでなくBluetoothやローカルWiFiでも可能である
- 優れたオフライン体験には、ブラウザタブよりもローカルにインストールされた実行ファイルのほうが適している
-
4. 同僚との円滑なコラボレーション
- 古いローカルファイルベースのソフトウェアは、複数人が同時に同じファイルを編集すると競合が起きやすい
- Google Docsのようなクラウドアプリは、複数ユーザーが同時にドキュメントを編集し、競合を気にしない体験を一般化した
- ローカルファーストの理想は、今日の最高のクラウドアプリと同等、あるいはそれ以上のリアルタイムコラボレーションを支援することである
- あるユーザーが変更を提案し、別のユーザーがレビューして選択的に反映する流れも重要である
- Google Docsのsuggesting mode
- GitHubのpull request
-
5. Long Now: 長期的なアクセス性
- データ所有権の重要な側面は、将来にわたって長くアクセスできることである
- 古いローカルアプリは、データと実行可能なソフトウェアのコピーがあれば使い続けられ、古いOSやコンピュータも仮想マシンやエミュレータで動かせる
- 保存媒体が変わっても、ファイルを新しい媒体へコピーできる
- クラウドアプリは、サービスが継続提供されるという前提に依存しており、サービス終了、データ損失、価格や機能の変更、望まない強制アップグレードに脆弱である
- ローカルファースト・ソフトウェアは、データとそのデータを読み書きするソフトウェアがローカルに保存されるため、長期保存の可能性が高まる
- plain text、JPEG、PDFは長く読める可能性が高く、米国議会図書館はデータセット保存形式としてXML、JSON、SQLiteを推奨している
-
6. デフォルトとしてのセキュリティとプライバシー
- クラウドアプリはすべてのユーザーデータを中央データベースに集めるため、攻撃者にとって魅力的な標的になる
- 内部の従業員やサーバーにアクセスしたハッカーがデータを読んだり改ざんしたりでき、データ侵害も一般的なリスクとして残る
- Google Driveの規約は、自動化システムがカスタマイズ検索結果、スパム・マルウェア検出のためにユーザーコンテンツを分析すると明記している
- 医療従事者、調査報道記者、政府・外交関係者のように機密性の高いデータを扱うユーザーは、クラウドアプリの利用が規制や守秘義務と衝突する可能性がある
- ローカルファースト・アプリは、各ローカルデバイスにユーザー自身のデータだけを保存し、サーバーにはエンドツーエンドで暗号化されたコピーだけを置ける
- iMessage、WhatsApp、Signal、Keybase、Tarsnapは、エンドツーエンド暗号化や暗号化されたファイル共有・バックアップの例として挙げられる
-
7. 最終的な所有権と制御権
- クラウドアプリでは、サービス提供者がユーザーのアクセスを制限できる
- 2017年10月、一部のGoogle Docsユーザーは自動システムが文書を誤って悪意あるものと判定し、文書へのアクセスを遮断された
- ここでいう所有権とは知的財産権ではなく、ユーザーの行為主体性、自律性、データの制御権を意味する
- ローカルファースト・ソフトウェアでは、データを構成するバイト列がユーザーのデバイス上にあるため、任意の方法で処理する自由がある
- データ所有権には、バックアップの維持、データ損失の防止、ランサムウェアへの対応、ファイルアーカイブ管理の責任も伴う
- ローカルファーストが必ずしもオープンソースである必要はなく、商用・クローズドソースのソフトウェアでも、ファイル利用を人為的に制限しなければ理想に近づける
- 人為的制限の例として、印刷を禁止するPDF、コピー&ペーストを妨げるeBookリーダー、メディアファイルのDRMが挙げられる
既存の保存・共有モデルの限界
-
ファイルとメール添付
- 従来のファイルは、オフラインでの閲覧・編集、ユーザーによる制御、バックアップ、長期保存、高速アクセスに強い
- 複数デバイスからのアクセスには、メール、USB、NAS/NFS/FTP/rsync、Dropbox系のファイル同期、Gitのような方式が必要になる
- メール添付は理解しやすく信頼しやすいうえ、6か月後でも添付ファイルが元の形のまま残っている
- 弱点はコラボレーションである
- 通常、一度に1人しかファイルを修正できない
- 複数人が編集すると手動マージが必要になる
Budget draft 2 (Jane's version) final final 3.xlsのようなファイル名の混乱が生じる
- ローカルファーストの考え方を適用しようとするアプリは、plain text、PDF、PNG、JPEGのような広くサポートされた形式へのエクスポートをまず提供できる
-
Webアプリ
- Google Docs、Trello、Figma、PinterestのようなWebアプリは、ブラウザやモバイルアプリが薄いクライアントで、データストアはサーバー側にある
- Webアプリはリアルタイムコラボレーションの標準を打ち立て、チーム作業で常に最新バージョンをどこからでも見られるという大きな利点がある
- その一方で、所有権と制御権は大きく低下する
- サーバー上のデータが正であり、クライアント側のデータはキャッシュに近い
- ネットワークが少し途切れただけでも、作業途中でアクセスできなくなることがある
- Google Docs offline plugin のような限定的なオフライン対応は、サーバー中心アーキテクチャに後付けされた形に近い
- MilanoteやFigmaのようなインストール型デスクトップクライアントも、本質的には再包装されたブラウザであり、ネットワーク障害・サーバー停止・サービス終了といった状況で限界が露呈する
-
Dropbox、Google Drive、Box、OneDrive
- Dropbox、Google Drive、Box、OneDriveは、デスクトップで指定フォルダを監視し、変更されたファイルを別のコンピュータへコピーする
- ローカルファイルシステムを使うため高速でオフライン作業が可能であり、同期サービスが終了してもローカルディスク上のファイルは残る
- ハードディスク障害が発生しても、アプリをインストールして同期を待てば復元できるため、長期性と制御権の面で利点がある
- モバイルのiOS・Androidでは、フォルダ全体を同期するのではなく、サーバーからファイルを1つずつ取得する薄いクライアントモデルに近い
- 「Make available offline」オプションは事前に指定しておく必要があり、煩雑で、アプリが開いているときにしか動作しない
- 最も弱い点はリアルタイムコラボレーションである
- 同じファイルが2つのデバイスで修正されると、手動マージが必要な競合が生じる
- 任意のファイル形式を同期できることは互換性の利点だが、形式ごとのマージができないという弱点にもなる
-
GitとGitHub
- Git と GitHub は主にソースコードの共同作業に使われており、現在ではローカルファーストに最も近いソフトウェアパッケージと評価されている
- Gitリポジトリはローカルファイルシステム上の主要なデータコピーであり、サーバーに従属しない
- 完全なオフライン作業、高速動作、ユーザー制御、長期保存への適性を提供する
- GitHubはコラボレーション、複数デバイスからのアクセス、バックアップとアーカイブの場所を提供するが、リポジトリを暗号化しない
- Gitの大きな弱点は2つある
- Google Docs、Trello、Figmaのような、きめ細かなリアルタイム自動マージ型の共同作業がない
- コードと行ベースのテキストに最適化されており、それ以外のファイル形式は意味のある編集やマージが難しいバイナリblobとして扱われる
- 多くのソフトウェアエンジニアがCloud9、Repl.it、Colaboratoryのようなクラウドベースのエディタ・実行環境を敬遠する理由として、「遅い」「信頼できない」「コードをローカルシステムに置いておきたい」を挙げる点は、ローカルファーストの動機と通じている
開発者インフラの観点から見た選択肢
-
薄いクライアントのWebアプリ
- Rails、Django、PHP、Node.jsのサーバーがSQLまたはNoSQLデータベースにデータを保存し、HTTPSでWebページを提供するモデルである
- インストールは不要で、ユーザーはURLを訪れるだけでよく、データ管理の責任はそれをデプロイしたエンジニアリング・DevOpsチームにある
- Meteor、ShareDB、Pusher、Ably、WebSocketは、Webアプリにリアルタイムコラボレーション機能をより簡単に組み込めるようにする
- ユーザーの行動ごとにサーバーへのリクエストが必要だと遅くなり、クライアント側JavaScriptで往復時間を隠しても、不安定なインターネット環境では簡単に破綻する
- manifest、localStorage、service worker、Progressive Web Appsといった取り組みにもかかわらず、Webアプリのアーキテクチャは根本的にサーバー中心である
- ブラウザでクッキーを削除するとローカルストレージのデータも一緒に削除されることが多く、長期的に重要なデータの保存には適していない
- オープンソースのWebアプリをユーザー自身がホスティングすれば一部の特性は改善できるが、ほとんどのユーザーはシステム管理者になりたがらないため、セルフホスティングは大多数にとって現実的な選択肢ではない
-
ローカルストレージを使うモバイルアプリ
- iOSとAndroidのアプリはバイナリをダウンロードしてローカルにインストールするが、Twitter、Yelp、Facebookのような多くのアプリはサーバーがなければ動かない薄いクライアントである
- SQLite、Core Data、通常のファイルのような永続化レイヤーによって、まずローカルデバイスにデータを保存するアプリは、ローカルファーストの理想により近い
- ClueとThingsは、単一ユーザー向けアプリとして始まり、その後デバイス間同期や共有のためにクラウドバックエンドを追加した事例である
- こうした厚いクライアントアプリでは、サーバー同期がバックグラウンドで行われるため高速で、オフラインでも動作する
- 複数デバイスや複数の共同作業ユーザーがデータを修正すると難易度が上がる
- モバイルアプリ開発者は通常、エンドユーザー向けアプリ開発の専門家であり、分散システムの専門家ではない
- 場当たり的な diff・merge・競合解決アルゴリズムは、信頼性が低く脆弱なことが多い
-
Firebase、CloudKit、Realm
- Firebase は、ローカルデバイスデータベース、クラウドデータベースサービス、両者の同期を組み合わせたモバイルBaaSである
- Firebaseは複数デバイスでの共有とオフライン利用をサポートするが、独占的なホスティングサービスであるため、プライバシーと長期性の評価は低い
- ParseはFacebookに買収された後、2017年に終了し、それに依存していたアプリは別のバックエンドへ移行しなければならなかった
- Firebaseコンソールは開発者にデータの閲覧・修正・削除の優れた体験を提供するが、ユーザーにはそれに相当するデータアクセス・操作・管理手段がない
- Appleの CloudKit は、iOSとMacに限定できるアプリに対してFirebaseに似た体験を提供する
- キー・バリュー型ストアと同期
- 優れたオフライン機能
- プラットフォーム内蔵により、アカウント作成・ログインの手間を軽減
- Realm はiOSのローカル永続化ライブラリとして人気を集め、Realm Object Serverはオープンソースかつセルフホスト可能で、サービス依存のリスクを減らす
-
CouchDB
- CouchDB は、複数のマシンが完全なデータベースのコピーを持ち、各レプリカが独立して変更を作成できる multi-master replication アプローチで注目されている
- Cloudantはそのホスティング版で、PouchDBとHoodieは同じ同期プロトコルを使いながら、エンドユーザーのデバイス上で動作するよう設計されている
- 思想的にはCouchDBはローカルファーストの原則に近いが、同時に変更されたデータについては、アプリケーションコードが明示的に競合解決しなければならない
- Google Docsのように、すべてのキーストロークが個別の変更になりうる細粒度のコラボレーションアプリでは、正しい競合解決コードを書くのは難しい
- 広く採用されなかった理由として、ユーザーごとに別DBを持つ際のスケーラビリティ、iOS・AndroidネイティブアプリへのJavaScriptクライアント埋め込み、競合解決、MapReduceクエリモデルへのなじみにくさが挙げられている
CRDTとより良い基盤技術
- 既存のアプリケーション開発向けデータ層は、ローカルファーストの理想をすべて満たしていない
- Ink & Switchは解決策を見つけるために3年前から研究を進めており、有望な基盤として Conflict-free Replicated Data Types、すなわち CRDT を提示している
- CRDTは2011年の学術的なコンピュータ科学研究で登場した汎用データ構造である
- ハッシュマップやリストのようなデータ構造と同様に文書の状態を保存するが、最初からマルチユーザー環境を考慮している
- テキストエディタ、スプレッドシート、ベクターグラフィックアプリはそれぞれの文書状態をデータ構造として保持しており、協調的なマルチユーザーアプリではこれをCRDTに置き換えられる
-
CRDTのマージ方式
- ユーザーはオフライン状態でもローカルデバイス上でアプリケーションの状態を見て修正できる
- CRDTは変更を追跡し、ネットワークが使えるときにバックグラウンドで他のデバイスと同期する
- 異なるデバイスで同時に新しいToDoを追加すると、マージ後の状態には追加されたすべての項目が一貫した順序で含まれる
- 別々のオブジェクトに対する同時変更は容易にマージできる
- 自動解決が難しいのは、複数のユーザーが同じオブジェクトの同じ属性を同時に更新する場合であり、CRDTは競合する値を追跡し、アプリまたはユーザーが解決できるよう残しておく
- CRDTはGitに似ているが、テキストファイルよりも豊かなデータ型に対して機能する
- 同期チャネルはサーバー、P2P接続、Bluetooth、USBメモリなど何でもよい
- 変更単位は単一のキー入力ほど小さくできるためGoogle Docs式のリアルタイム共同編集が可能であり、Gitのpull requestのように大きなまとまりで送ることもできる
-
AutomergeとHypermerge
- Ink & SwitchはオープンソースのJavaScript CRDT実装 Automerge を開発した
- AutomergeはJSON CRDT研究を基盤としている
- Automergeと Dat networking stack を組み合わせて Hypermerge を作った
- これらのライブラリがローカルファーストの理想を完全に実現していると見るのは難しく、まだ多くの作業が必要である
- CRDTは、インターネットのpacket switchingやスマートフォンのcapacitive touchscreenのように、ユーザーがデータの所有権を持つ共同編集ソフトウェアの基盤技術となる可能性がある
Ink & Switchのプロトタイプ
- CRDTアルゴリズムと理論検証は学界で進展してきたが、産業での利用はまだ少なく、その多くはサーバー中心コンピューティングで使われている
- CRDTを使うサーバー中心システムの例として、Azure Cosmos DB、Redis、Riak、Weave Mesh、SoundCloud Roshi、Facebook OpenRが挙げられている
- Ink & Switchは、エンドユーザーデバイスでCRDTを使う創作作業向けのローカルファースト共同編集アプリのプロトタイプを作成した
- 実験は3つの問いを扱う
- 技術的可能性: CRDTは実際のソフトウェアにどれほど近づいているか
- ユーザー体験: 中央の権威サーバーなしでGoogle Docsのようなリアルタイム共同編集と、Gitのようなオフラインに強い非同期コラボレーションが可能か
- 開発者体験: CRDTデータ層はSQL DB、ファイルシステム、Core Dataとどう異なるか
- 3つのプロトタイプはElectron、JavaScript、Reactで作られており、ダウンロードしてインストールできるソフトウェアである点が所有感に重要だと考えられている
-
Trellis
- Trellis はTrelloをモデルにしたKanban boardである
- ネットワーク通信層としてWebRTCを実験した
- GitとGoogle Docsの「See New Changes」に着想を得た変更履歴を設計した
- ユーザーはKanban boardの作業を確認し、文書の以前の状態に戻って見ることができる
-
Pixelpusher
- Pixelpusher は、Javier ValenciaのPixel Art to CSSにFigmaのようなリアルタイム共同編集体験を加えた共同描画プログラムである
- DatプロジェクトのP2Pライブラリでネットワーク通信を実験した
- 文書共有URL、Gitに着想を得た視覚的なbranch/merge、競合ピクセルを赤色で強調する競合解決、ユーザーが描いたアバターに基づく基本的なユーザー識別を実験した
-
PushPin
- PushPin はMiroやMilanoteに似たmixed media canvas workspaceである
- Automergeベースの3つ目のプロジェクトで、3つのプロトタイプの中で最も完成度が高かった
- チームと外部テストユーザーによる実際の使用は、underlying data layerにより大きな負荷をかけた
- ネストされ相互接続された共有文書、CRDT文書向けのさまざまなレンダラー、outboxモデルを含むより発展したアイデンティティシステム、選択範囲の強調のような一時的データ共有を実験した
プロトタイプから得られた結果
- 3つのプロトタイプの目標は、ローカルファースト・ソフトウェアとCRDTの技術的実現可能性、ユーザー体験、開発者体験を評価することだった
- 開発チーム5人が定期的に使用し、約10人の外部ユーザーと個別のユーザビリティテストを実施した
- 外部ユーザーには、プロのデザイナー、プロダクトマネージャー、ソフトウェアエンジニアが含まれていた
- 正式な評価手法ではなく、探索的アプローチを用いた
-
CRDT技術は機能する
- Automergeの信頼性は予想以上に高かった
- チームのアプリ開発者はライブラリを比較的容易に統合でき、データの自動マージはほとんど常に直感的でスムーズだった
-
オフラインのユーザー体験は良好だった
- オフラインに切り替えて好きなだけ作業し、再接続後に同僚の変更とマージする流れはうまく機能した
- 他のアプリが「offline」警告やエラーを表示して作業を妨げるときでも、ローカルファーストのプロトタイプはネットワーク状態に関係なく正常に動作した
- ブラウザベースのシステムと違って、アプリが動くか、データがあるかを不安に思う必要が減り、ツールと成果物に対する所有感を与えた
-
ReactのFRPモデルと相性が良い
- ReactのFunctional Reactive ProgrammingモデルはCRDTと相性が良い
- CRDTベースのデータ層では、ドキュメントがローカルユーザー入力とネットワーク経由で来た他のユーザー・デバイスからの変更を同時に受け取る
- FRPモデルは、表示されるアプリケーション状態を共有ドキュメントのunderlying stateと安定して同期する
- 開発者は、他のユーザーから来た変更を追跡し、現在の画面と調整する煩雑な作業から解放された
- すべての状態変更を単一のreducer関数に通すことで、関連するローカル変更を他のユーザーへ送ることも容易になった
-
衝突は予想より深刻ではなかった
- ユーザーは共同作業中に衝突に遭遇することがまれで、一般的な解決メカニズムはうまく機能した
- Automergeは細かな粒度で変更を追跡し、データ型の意味を考慮する
- 2人のユーザーが配列の同じ位置に項目を同時に挿入すると、2つの項目を決定的な順序で結合する
- Gitのようなテキストのバージョン管理システムでは、これを手動解決が必要な衝突と見なす可能性がある
- ユーザーはコラボレーションに対する直感を持っており、同じセクションを同時に編集しないよう作業領域を暗黙的に分けることがある
- Kanbanアプリでは、あるユーザーがカードにコメントを付け、別のユーザーがカードを別のカラムへ移動すると、両方の変更が反映される
- 衝突は同じオブジェクトの同じ属性を同時に編集した場合にのみ発生し、例として2人のユーザーが同じ画像オブジェクトの位置を同時に変更するケースが挙げられている
- プロトタイプではAutomergeのデフォルトのマージセマンティクスだけで十分であり、カスタムセマンティクスが必要な事例は見つからなかった
-
ドキュメント履歴の可視化が重要
- 分散コラボレーションシステムでは、他のユーザーの変更がいつでも多数到着しうる
- 中央サーバーが変更を媒介しないため、ドキュメントが現在の状態になった経路、存在するバージョン、貢献元を理解するためのツールが必要になる
- Trellisは、ユーザーがマージ済みドキュメントの過去の状態へ移動して見られる「time travel」インターフェースを試した
- 新たに受け取った変更要素を自動で強調表示する方式も試した
-
URL共有は自然だった
- 複数のドキュメント共有メカニズムの中で、Webに着想を得たURLモデルがユーザーにも開発者にも最も自然だった
- URLはコピー&ペーストでき、メールやチャットのような通信チャネルで共有できる
- 秘密URLを超えるドキュメントアクセス権は、依然として未解決の研究課題として残っている
-
P2Pシステムは単純なオンライン・オフラインには分けられない
- 中央集権型システムは通常、サーバーとの安定した接続の有無によって「up」または「down」の状態を定義する
- 分散システムでは、各ユーザーがどのデータを持ち、共有し、受け入れるかによって、それぞれ異なる視点を持ちうる
- 飛行機内のノートPCにあった編集内容は、着陸後に接続されれば他のユーザーへ配布できる
- 他のユーザーは、その変更のすべて、一部、または何も自分のドキュメント版に受け入れない可能性がある
- Gitリポジトリのように、特定ユーザーの「master」は最後に他のユーザーと通信した時点の関数になる
- 分散ドキュメントはデータの統制権をユーザーに与えるが、それが実際のUIの観点で何を意味するのかは、さらに研究が必要である
-
長い変更履歴は性能問題を生む
- PushPinをスプリント計画のような実際のドキュメントで使うと、性能とメモリ・ディスク使用量が急速に問題になった
- CRDTは文字単位のテキスト編集を含め、完全な履歴を保存する
- 6か月後に誰かが再びドキュメントへ接続し、その時点から変更をマージしなければならない可能性があるため、履歴を簡単に切り捨てることはできない
- Automergeの最適化は継続中であり、主要な進行中の作業領域のままである
-
ネットワーク通信はまだ解決されていない
- CRDTアルゴリズムはデータのマージだけを扱い、他ユーザーの編集が物理的に同じコンピュータへ到達する方法までは扱わない
- 実験では、WebRTC、DropboxやUSBキーでファイルをコピーするsneakernet実装、IPFSプロトコルの可能性、DatのHypercore P2Pライブラリを試した
- CRDTは必ずしもP2Pネットワーク層を必要とせず、サーバー経由の通信も可能である
- ローカルファーストの長期的な目標を完全に実現するには、ベンダーのバックエンドサービスより長く存続する分散型の解決策が論理的な最終目標となる
- P2P技術は本番運用の準備が不足しており、とくにNAT traversalはルーターやネットワークトポロジーによって信頼性が低かった
- インターネット接続なしでコンピュータ同士が直接リアルタイムに共同作業する体験は、中央APIに依存する世界において大きな可能性を示している
-
クラウドサーバーは補助的な役割にとどまる
- PushPinのようなリアルタイム共同作業プロトタイプは、中継サーバーなしでドキュメントを共有でき、プライバシーと所有権の面で有利である
- しかし、ユーザーがドキュメントを共有した後、相手が接続する前にノートPCを閉じてしまうと、2人のユーザーが同時にオンラインではないため接続できない
- サーバーはローカルファーストの世界で中央権威ではなく、cloud peerとして機能できる
- ドキュメントのコピーを保存し、他のピアがオンラインになったときに配送する
- アーカイブ・バックアップの場所を提供する
- 天気予報や株価のような従来型サーバーAPIへのブリッジ
- 強力なGPUで動画レンダリングのようなburst computingを提供する
- 従来システムとローカルファーストシステムの違いは、サーバーの有無ではなく、サーバーが真実の源泉ではなく支援役を担う点にある
今後必要な取り組み
-
分散システム・プログラミング言語の研究者
- CRDTとP2P技術の研究は、ローカルファースト・ソフトウェアに大きく貢献しうる
- 現在のCRDT研究は、通常、すべての共同編集者が単一の文書バージョンに編集を即座に適用するモデルを前提としている
- 実際のローカルファーストアプリでは、他の共同編集者の編集を拒否したり、共有しない文書バージョンに非公開の変更を加えたりできる必要がある
- branch、fork、rebaseのような分散ソース管理の概念を、複数の文書バージョンとbranchが並行して存在する共同編集モデルへ拡張する研究は不足している
- 型、スキーママイグレーション、互換性も重要な問題である
- 共同編集者ごとに異なるアプリのバージョンや機能を使っている可能性がある
- 中央DBサーバーがないため、データの権威ある「現在」のスキーマは存在しない
- データ形式が進化するあいだ、複数のアプリバージョンが安全に相互運用できなければならない
-
HCI研究者
- 中央集権型システムにはサーバーとの同期状態を表示する例が多いが、分散型システムは新たなUI上の問題を抱えている
- すべてのユーザーがデータの異なるコピーを持ちうるシステムで、オンライン・オフライン、利用可能・利用不可の状態をどう伝えるかについて研究が必要である
- 広域インターネットなしで他のノードと直接共同作業できる場合、「オンライン」が何を意味するかも変わってくる
- 日常的な利用だけで、すべての文書が複雑なバージョン履歴を持ちうるため、ユーザーがバージョン、変更の受け入れ、文書形成の過程を理解できるUIが必要である
- 現在の変更管理は、ソースコード型のdiff・patchモデルとGoogle Docs型のsuggestion・commentモデルが主流である
- テキストではないデータ形式にこの考え方を一般化する方法は未解決の課題である
- ローカルファーストでは、データを持つユーザーがローカルで修正することを止めることはできず、他のユーザーがその変更を購読するかどうかを選ぶ形へと権限の概念が変わる
-
実務家
- 本番ソフトウェアを作るエンジニア、デザイナー、プロダクトマネージャー、独立開発者は、ローカルファーストの未来へ向けた段階的なステップを取ることができる
- 高速なアプリのために、積極的なキャッシュと事前ダウンロードで文書を開く際のスピナーを減らし、基本的にローカルキャッシュを信頼できる
- マルチデバイスはFirebaseやiCloudのような同期インフラで比較的容易に対応できるが、長期継続性とプライバシーへの懸念がある
- オフライン対応については、WebではProgressive Web Apps、Service Workers、app manifestが役立つ
- アプリのテストは、WiFiを切るか、Chrome DevTools network condition simulator、iOS network link conditionerのようなツールでネットワーク条件を変えて行える
- コラボレーションでは、CRDTに加えて、ShareDBなどに実装されているOperational Transformationのほうがより確立された技術である
- 長期保存のためには、JSON、PDFのような安定した形式へ容易にエクスポートできる必要がある
- Google Takeoutのような一括エクスポート
- GoodNotesの安定したファイル形式による継続的バックアップ
- TrelloのJSON文書ダウンロード
- プライバシーの観点では、データがデバイスのみに保存されるのか、バックエンドへ送信されるのかをユーザーに明確に知らせるべきである
- ユーザーのコントロール権のために、アプリ内で文書のバックアップ、複製、削除が容易であるべきであり、Google DocsがGoogle Driveによって基本的なファイルシステム操作を再実装した事例が挙げられている
スタートアップの機会と結論
- 開発者向けインフラを作ろうとする起業家にとって、「Firebase for CRDTs」は興味深い市場機会として提示されている
- そのようなスタートアップは、優れた開発者体験とSQLiteやRealmのようなローカル永続化ライブラリを提供すべきである
- iOS、Android、Windows、Mac、Linux、Electron、Progressive Web Appsをサポートすべきである
- ユーザーのコントロール権、プライバシー、マルチデバイス対応、コラボレーションが標準で含まれていなければならない
- 成功可否のリトマス試験紙は、すべてのサーバーが停止しても顧客アプリが永続的に動作し続けるかどうかである
- クラウドソフトウェアは、共同作業とどこからでもアクセスできる最新のアプリを提供したが、データ所有権をサーバー側に置くことで、ユーザーを自分のデータの借家人のような存在にしてしまった
- ローカルファーストのアプローチは、ユーザーがデータの所有権とコントロール権を維持しながら、クラウド型の共同作業とアクセス性も得られることを示している
- 実際に実装するには、オフライン対応、オンデバイスストレージの活用、アルゴリズム・プログラミングモデル・ユーザーインターフェースの改善、CRDTとP2Pネットワーキングのプロダクト化がさらに必要である
1件のコメント
Hacker Newsの意見
完全に同意。あらゆるサービスが自分のデータを向こうのクラウドに持っていき、まともに使うにはサブスクリプション料金を払わせる流れにはうんざりしている
今作っているフィットネストラッキングアプリは、「一度購入すればX年間アップデートを受けられ、すべてのデバイスと同期でき、その後も永久に使える」というモデルにしようとしている。X年後にアップデートが必要なら新バージョンを再度買えばいいし、今の機能で十分ならそのまま使い続ければいい
ほとんどのソフトウェアが、こうして適正価格で購入でき、製品自体が優れていて、クラウドなしでは使えないように縛られていないものになってほしい。ローカルファーストソフトウェアのいちばん良い点は、広告・トラッキング・エンゲージメント最大化ではなく、製品の品質で対価を得る健全なインセンティブを復活させることだ
ノートはすべてMarkdownファイルなので、クライアント自体も選択肢の一つになる
同期サーバーも継続して運用しなければならないし、ユーザーが1年分のデータを1日にまとめて同期するケースも考慮する必要がある。将来の開発を担う人員にも給料を払い続けなければならないので、開発者視点だけで見ると抜け落ちる部分がある
https://rodyne.com/?p=1439
私たちが作っているノート/タスクIDEもこの方式: https://thymer.com/local-first-ejectable
ベルリンにはInk and Switchが主催する年次のLocal-first Software Conferenceがあり、今年11月にはSFでSync Confという派生イベントも開かれる
https://www.localfirstconf.com/
https://syncconf.dev/
今年は、元論文の共著者たちが、開発ツールの文脈でローカルファーストソフトウェアとは何か、元論文以降に何を学んだかを扱ったパネルが良かった: https://youtu.be/86NmEerklTs?si=Kodd7kD39337CTbf
コミュニティでは、「同期」はローカルファーストの構成要素ではあるが、はるかに広く適用できる技術だ、という方向に整理されつつある。ローカルファーストはエンドユーザー向けソフトウェアの特性であり、同期エンジンのような開発ツールはそれを可能にする道具であって、それ自体が必ずしもローカルファーストというわけではない
過去数年間の発表全体はこちらにある: https://youtube.com/@localfirstconf?si=uHHi5Tsy60ewhQTQ
ローカルファースト/同期エンジンのコミュニティにとっては興味深い時期だ。リアルタイム共同編集と非同期コラボレーション体験を可能にするツールを作ってきたところに、AIの登場でこの市場が拡大している。あらゆるAIアプリは本質的に、エージェントがアクターとして参加するマルチユーザー協調システムなので、同期エンジンコミュニティが扱ってきた技術を必要とする
https://www.localfirst.fm/
読む価値があり、過去にも活発な議論が何度もあった
https://news.ycombinator.com/item?id=19804478 - 2019年5月、コメント191件
https://news.ycombinator.com/item?id=21581444 - 2019年11月、コメント241件
https://news.ycombinator.com/item?id=23985816 - 2020年7月、コメント9件
https://news.ycombinator.com/item?id=24027663 - 2020年8月、コメント134件
https://news.ycombinator.com/item?id=26266881 - 2021年2月、コメント90件
https://news.ycombinator.com/item?id=31594613 - 2022年6月、コメント30件
https://news.ycombinator.com/item?id=37743517 - 2023年10月、コメント50件
オンライン依存があるものは、必然的に継続的な保守とコストがかかります。システムがローカル優先、できればローカル専用でなければ、長期的な信頼性を考えて設計されたものではありません。
接続された家電や自動車は、実用的な観点では最も愚かなエンジニアリングに近いものです。
サブスクリプション収益を得る企業は売上も多く、バリュエーションも高いため追加資金を調達しやすくなり、このモデルに従わない企業に勝ちます。こうした自己強化構造のせいで、ローカル優先ソフトウェアは死んだのだと思います。
Cloudflareは静的ファイルホスティングをほぼ無料で提供しており、コストは丸め誤差に近いものです。ローカル優先アプリ1000個がDropboxに同期しても、月10ドルのストレージで回せるはずです。このストレージはS3のような低レベルの生のツールではなく、認証、サポート、同期プログラムまで備えた消費者向けサービスです。ほとんどのクラウドコストは、実は必要ありません。
ゲームをオンラインサービスだけに依存させることを、誰も強制していません。法的要件でも規制上の要件でもありません。ソフトウェアの多くと同じく、単なる選択です。オンラインサービスに依存するよう選択しておいて、後になって「これを元に戻すにはお金がかかる」と言うのは近視眼的で情けなく、受け入れるべきではありません。
もっと多くのアプリがローカル優先であるべきです。ユーザーがデータをクラウドに同期したくないなら、その選択肢があるべきです。
しばらく前からオフライン優先、またはローカル優先のアプリBrisqiを作っており、最初からオフライン優先の哲学で設計しました。
https://brisqi.com
ローカル優先アプリは、無期限に完全オフラインで動作するよう設計されるべきです。ローカル体験が基盤であって代替手段ではなく、クラウド同期は要件ではなく補助機能であるべきです。
一時キャッシュに依存するアプリは、オフライン優先とは見なしません。本当にオフライン優先のアプリは、ローカルデータベースでデータを永続化する必要があります。「オフライン優先」と呼ばれる多くのアプリは、実際には限定的なオフライン機能だけを提供し、結局はインターネットへの再接続に依存するオフライン許容型に近いものです。
オフライン優先アプリは、オンライン専用のWebアプリより確実に作るのが難しく、オフライン/オンライン切り替え中でもデータが一貫してクラウドへ同期され、失われないように、同期メカニズムが十分に信頼できなければなりません。アプローチについてはブログにもう少し書いてあります: https://blog.brisqi.com/posts/how-i-designed-an-offline-first-app-an-outline
この原則を消費者領域に合わせて説明している点は興味深いですが、私たちは現在産業資産/産業データの領域で同じことをしています。
www.sentineldevices.com では、学習、分析、意思決定のすべてが顧客の設備上で行われます。データを送るサーバーすらなく、明示的にすべてがデバイス内で動くモデルです。
SCADA/産業オートメーションでは、データを外部に持ち出せないユースケースが数多くあります。顧客のいる場所でサービスを提供するのが難しいという理由で、データ/AI企業は巨大な顧客層とユースケースを無視し、その代わりにデータを自分たちのところへ持ってこさせ、ベンダーロックインを維持しようとしています。
顧客と話すときは、むしろ「いいえ、これはローカルで、外部接続はありません」とかなり強調する必要があります。こうした話をほとんど聞いたことがないため、段階的に説明して初めて、すべてがローカルで起きているのだと理解してもらえることが多く、ソフトウェアベンダーたちはこの概念をなかなか受け入れません。消費者領域でローカル優先ソフトウェアがもっと定着し、産業領域でも馴染みのあるものになるとよいと思います。
「スマートフォンで工場を運用しましょう!」とは。これでゼロデイが1つ出るだけで、スクリプトキディが私のポンプで遊べるようになります。
採用ページを見ると、すべてのポジションが非リモートのようでしたが、ローカル優先ソフトウェアを作るには直接対面する必要があるという制約のためなのか、それとも主に管理上の理由なのか気になります。
個人的にはこのアプローチには同意しない。「クラウドプロバイダーを信頼できない」というビジネス上の問題を、「中央集権型アーキテクチャを避ける」という技術的なトレードオフで解こうとしているように見える
クローズドソースソフトウェアにおけるコントロール不足と信頼性不足は、オープンソース開発という新しいビジネスモデル、新しいライセンス、ライセンス費用の代わりに保守契約で収益を得る方式によって解決されてきた
同じように、クラウドプロバイダーの問題にもビジネスモデルのレベルでの解決策が必要だ。たとえば、ユーザーがクラウドプロバイダーとの関係を信頼できるよう、権利を定義する標準契約/ライセンスを作ることができる。時間がたてば、ユーザーはそうしたライセンスを持つプロバイダーとだけ取引するようになるかもしれない
そこには、サービス終了時の契約、データポータビリティの保証、データアクセスを監査し、誰が/何が/いつ読んだのかを知らせるデータプライバシーの透明性のような条項を盛り込める。問題は採用だ。クラウドプロバイダーがなぜそれを受け入れるべきなのかが核心であり、解約率を恐れるなら、こうした契約を年額サブスクリプションにだけ提供したり、より高い価格を設定したりすることもあり得る
クラウドサービスを使うときの暗号化がよい例だ。プライバシーポリシーや官僚的なルールでデータを守ろうとするのは、ほとんど無駄に近い。データには価値があり、顧客や政府は企業がこっそり売っているかどうかを知りにくく、セキュリティ費用をケチっていたかどうかも、手遅れになるまで分かりにくい
しかし、クライアント端末上で暗号化され、サーバーが平文にアクセスできないことを数学的に証明できるなら、そうした心配は不要になる。問題は、サーバーがデータを保存するだけでなく処理もしなければならない場合で、そのときの技術的な解決策は自分のサーバーを使うことになる
自分でアプリを作るか、親切な誰かが作ってくれない限り活用しにくい。何もないよりはましだが、会社が倒産したりサポートを打ち切ったりした後でも何年、あるいは何十年も動き続けられるローカルアプリほど良くはない
回収は金融では金銭や財産の引き渡しに相当し、クラウドではアカウント全体の内容を含む大きなZipファイルを受け取ることかもしれない
だが、引き渡しを受けることが常に実用的または望ましいとは限らない。金融では口座を別の事業者へ移管でき、クラウドサービスでも多くの場合、アカウント移行の方がはるかに有用である可能性が高い
ここで難しいのはポータビリティだ。クラウドアカウントに対するユーザーの財産権や権利をうまく定義したとしても、Facebookの友達を引き渡してもらうとはどういう意味なのか、Facebookアカウントを別の場所へ移行するとは何を意味するのかは曖昧だ
この問題にはビジネス上の解決策と技術的な解決策の両方が必要であり、論文は解決策がどのような性質を持つべきかを提案している
ローカルファーストが分散化を主張しているというのも正しくない。Martin Kleppmannは、分散型技術が大衆市場に届く形でこの問題を解決するとは見ていないと明言している。彼はローカルファーストの理想を可能にする中央集権型の標準同期エンジンを支持している
昨年のLocal-first confでの発表を参照: https://youtu.be/NMq0vncHJvU?si=ilsQqIAncq0sBW95
危機的状況では数週間でも可能だが、非常に雑なものになり得る。同じバージョンのオープンソースデータベース間で移す場合でも、クラウドサービスごとに違いが多く、事情は同じだ
最良の解決策は、そもそもデータを自分の環境に置き、必要なら接続を切ることだ。BYOC管理とオープンソースを組み合わせれば可能になる。私たちの会社もBYOCデータ製品を運営しているので、このアプローチには経済的な利害関係があるが、実際に機能するのを見てきたので可能だと分かっている
私のプロジェクト https://github.com/ibizaman/selfhostblocks と https://github.com/ibizaman/skarabox で、まさにそれを広く可能にしようとしている
共通の目標は、セルフホスティングを一般の人にとってより手の届くものにすること
NixOS ベースで、https、SSO、LDAP、バックアップ、スナップショット付きの ZFS などを、できるだけ宣言的に標準提供しようとしている
Vaultwarden と Nextcloud をパッケージ化して大半のデータを保存できるので、クラウドホスティングの競合になり、Home Assistant のようなサービスも提供する
YUNoHost の競合でもあるが、SelfHostBlocks が提供する構成要素を使って、望むパッケージを自分でセルフホストできるので、より良い、あるいはそうなろうとしている。フレームワークというよりライブラリに近い
NAS とも競合するが、すべてがオープンソースである点でより良いと思う。現時点ではまだユーザーに技術力が必要だが、その制約をなくしているところで、目標の一つは、Nix を知っていたりコマンドラインを触ったりしなくても、自分のハードウェアにインストールできるようにすること
セルフホスト可能なアプリのかなり多くは、データベース、サーバー、フロントエンドを持つ Web アプリケーションだが、多くのユースケースでは 1 台のコンピュータだけで使い、ホスト版や他のデバイスとの同期が不要なこともある。たとえば個人会計は月に一度コンピュータでやればよいので、どこかで 24 時間 Web アプリを動かす必要はない。プログラムを起動して作業し、終わったら閉じればよい
高品質なセルフホスト可能な自由・オープンソース代替の数と、実際にそれを使える人の数のあいだには大きな不一致がある。そのギャップを縮めるプロジェクトがもっと必要だ。selfhostblocks をいくつかの用途で試し、貢献してみたい
すべてのアプリケーションが独自の同期プラットフォームを持つ理由はない。こうした捉え方は、プログラム間の組み合わせ可能性やモジュール性がないモバイルアプリから来ているように思える
「ローカルファースト」を真剣に受け止めるなら、単にファイルシステムを使えばよく、ユーザーは git、Box など複数の解決策から選べる
独自の同期サブスクリプションを求めるのは他の SaaS と同じくらい嫌だし、むしろより不透明で壊れやすい
第一に、ローカルファーストも望むが、同時性も望む。単純なローカルファーストならどんな同期でも構わないが、それ以上を望んでいる。Dropbox のように意識しなくても滑らかに動き、通信できない地域でも、私と妻がそれぞれのスマートフォンで別々に編集できるようにしたい
第二に、同期はデータ構造と意味を深く理解していると、はるかにうまく機能する。git と Box はどちらもかなりの限界があり、同時性の要件があるとその限界はさらに大きくなる
理論的にはローカルファースト方式の開発は好き。プライバシーとデータ所有権を基本とするスモールテックの思想とよく合っている
ただし実際には難しい。事実上、同期エンジンを作り、コンフリクト解決を扱い、スキーママイグレーションを管理しなければならない
それでもここ数年で、ローカルファーストソフトウェアの開発ツールは良くなってきたように思う。jazz.tools、electric-sql、Rocicorp の Zero を追っているが、ほかにもあるのか気になっている
https://couchdb.apache.org/
https://pouchdb.com/
約10年前のローカルファーストアプリケーション開発に関するさらなる考察は、ここでも見られる: https://unhosted.org/
ブログ記事を書くべきだが、以前は PowerSync、electricSQL、LiveStore、PowerSync を調べ、jazz.tools も少し見たものの、もう少し構造化されたものが欲しかった
今のところかなり印象は良い。Vue とコミュニティライブラリで書いていて、権限まわりは少し厄介だったが、理解するとシンプルだった。マジックメールログインも気に入っているし、ダッシュボード/レスポンス機能も良いが、もっと手間を減らすにはいくつか大きな変更が必要そうだ
オープンソースで、望めばセルフホストできる点が良い。jazz は構造が足りず、LiveStore はイベントストアがあまりに面倒に見えたが魅力はあった。開発ツールが有料の壁の向こうにあるのは残念だったが、理解はできる。electricSQL は解決策の半分、つまり読み取りだけを提供し、書き込みモデルが不足していた。CouchDB/PouchDB も自分には構造が足りず、ドキュメント間のサポートがもっと明確に組み込まれていることを望んでいた。Zero はきちんと調べていない
実は上部メニューの “landscape” リンクを指そうとしたのだが、URL がかなり扱いにくい
https://automerge.org/
Rust と JavaScript の実装があり、いくつかのネットワーク戦略も提供している。jazz.tools のような無料/有料の製品構成は付いてこないが、かなり良い
https://www.ditto.com
CRDT を中核にリアルタイム同期をサポートするローカルファーストプラットフォームなので、コンフリクト解決の管理がずっと楽になる。オフラインファーストのユースケースとピアツーピア同期を標準で扱うよう設計されており、同期エンジンを自分でゼロから作る必要がない
Swift、Kotlin(Android)、Flutter/Dart、React Native、JavaScript(Web/Node)、.NET(C#)、C++、Java、Rust など、さまざまなプラットフォームをサポートしている。ドキュメントはこちらでさらに見られる: https://docs.ditto.live/home/about-ditto