ネットワークを殺す:ローカルファーストの真髄
多くのWebアプリケーション開発において、我々エンジニアが直面する最大の敵は「ネットワークレイテンシ」だ。ユーザーがボタンをクリックし、HTTPリクエストが飛び、サーバーがDBを叩いてレスポンスを返す。この往復にかかる数百ミリ秒の空白が、UIにスピナーやスケルトンを表示させ、ユーザー体験を著しく損なう。Linearがなぜこれほどまでに「爆速」と感じられるのか。その答えは、彼らが伝統的なCRUDアプリのアーキテクチャを根本から覆し、ブラウザを単なるビュー層ではなく「データベースそのもの」として扱っている点にある。
Linearのアーキテクチャにおいて、UIはIndexedDB上のデータを直接読み込む。ユーザーがタスクを更新する際、まずローカルのMobXストアが即座に更新され、UIが再描画される。サーバーへの同期はバックグラウンドで非同期に行われる。これは単なる「楽観的UI(Optimistic UI)」の域を超えた、設計思想の転換だ。多くの開発者がTanStack QueryやSWRで楽観的更新を実装して満足しているが、Linearは最初から「同期エンジン」をコアとして構築している。Tuomas氏が語った通り、創業初期からこの同期エンジンを最優先で実装したという事実は、彼らが「ネットワークの遅延を隠蔽する」という一点にどれほどの執念を燃やしていたかを物語っている。
我々が明日から取り入れるべきは、この「UIの応答性をネットワークの完了から切り離す」という設計だ。サーバーからのレスポンスを待つのではなく、ローカルの状態を正とし、競合解決や同期をバックグラウンドに押しやる。このアプローチは、複雑な状態管理を強いるが、ユーザーに「アプリが自分の思考速度に追いついている」という圧倒的な没入感を与える。もしあなたが今、スピナーを回すことに慣れきったコードを書いているなら、それは技術的な敗北を意味しているのかもしれない。
ビルドパイプラインの執念とモダンスタックの選択
Linearのフロントエンドスタックを眺めると、驚くほど「シンプル」であることに気づく。React、TypeScript、MobX、そしてPostgres。React Server Componentsのような流行の技術に飛びつくのではなく、クライアントサイドレンダリング(CSR)を極限まで磨き上げている。彼らがParcelからRollup、Vite、そしてRolldownへとビルドパイプラインを4回も刷新してきた事実は、単なる技術的興味ではない。それは「いかにしてブラウザに届けるJavaScriptの量を削り、実行速度を最大化するか」という、泥臭い最適化の歴史そのものだ。
彼らはレガシーブラウザのサポートを切り捨て、ESM(ECMAScript Modules)を前提としたモダンな環境に特化することで、ポリフィルやトランスパイルのオーバーヘッドを排除した。結果として、約21MBもの巨大なコードベースを抱えながらも、ルートレベルでのアグレッシブなコード分割と、npmパッケージ単位でのキャッシュ戦略により、体感速度を維持している。特に注目すべきは、ビルド時の最適化だ。manualChunksを用いた依存関係の分離により、ライブラリの更新がアプリ全体のキャッシュを無効化しないよう制御されている。これは、大規模なフロントエンド開発において、キャッシュヒット率を最大化するための極めて実践的な知見である。
以下に、Linearが採用している主要な技術スタックの構成要素を整理する。
| レイヤー | 技術要素 |
|---|---|
| UI Runtime | React, MobX, Radix UI |
| Build Tool | Rolldown, Vite, LightningCSS |
| Data/Sync | IndexedDB, GraphQL, Yjs (CRDT) |
| Backend | Node.js, PostgreSQL, Redis, Cloudflare Workers |
この構成から読み取れるのは、流行に流されるのではなく、自分たちのプロダクトが抱える「状態の複雑さ」を解決するために最適な道具を選び抜くという姿勢だ。特に、ProseMirrorとYjsを組み合わせたリッチテキストエディタのリアルタイムコラボレーション実装は、彼らの技術的深さを象徴している。我々エンジニアは、新しいフレームワークが出るたびに「これを使えば速くなるのか?」と自問しがちだが、Linearの事例は「フレームワークの選択よりも、データの流れと同期の設計こそが速度の源泉である」という真理を突きつけている。
エンジニアへの問い:速度は機能か、それとも文化か
Linearの成功は、単に技術的な最適化の賜物ではない。それは「ユーザーの時間を奪わない」という強い意志が、コードの隅々にまで浸透している結果だ。多くの企業がJiraのような巨大なレガシーシステムからLinearへ移行する理由は、単にUIが綺麗だからではない。彼らが提供しているのは「思考を中断させない」という、生産性ツールにおける究極の機能価値である。しかし、ここで我々エンジニアは自問しなければならない。我々の開発現場において、パフォーマンスは「後回しにされる非機能要件」になっていないだろうか。
「まずは動くものを作れ」というアジャイルの教義は、しばしば「技術的負債を積み上げ、後で最適化すればいい」という言い訳にすり替わる。しかし、Linearの事例は、同期エンジンという最も複雑な部分を最初から設計に組み込むことで、後からの修正コストを劇的に下げていることを示唆している。もしあなたが今、パフォーマンスの問題を「ハードウェアの進化」や「ユーザーの回線速度」に転嫁しているなら、それはエンジニアとしての怠慢ではないか。Linearが示したのは、ブラウザという制約の多い環境であっても、設計次第でネイティブアプリに匹敵する体験を構築できるという可能性だ。
明日からあなたが取るべきアクションは明確だ。まず、自分のアプリケーションで「ネットワークリクエストを待っている時間」を計測すること。そして、そのリクエストをUIの更新から切り離すために、どの程度の設計変更が必要かを試算すること。Linearのような速度は、魔法ではなく、徹底した「ネットワークの隠蔽」と「ローカル状態の管理」という地道な積み重ねから生まれる。あなたは、ユーザーの時間を奪うスピナーを、あと何回表示し続けるつもりだろうか?そのスピナーを消し去るために、今日、どのような設計の決断を下すのか。それが、シニアエンジニアとして問われている本質的な課題である。


コメント