9月23日、Anthropicの開発者向けブログ「claude.dev」が「How we made claude.ai 3x faster in two weeks」と題した記事を公開した。claude.aiとClaudeデスクトップアプリを2週間のスプリントで約3倍高速化した取り組みを、技術的な詳細とともに紹介したものだ。
驚くべきは速度改善の幅だけではない。この2週間で3,000件以上の変更をマージしたが、ユーザー向けのインシデントもロールバックも一件もなかった。その裏側にあった「計測・最適化・ガードレール」を同時並行で回す体制の詳細が、エンジニアリングブログで公開された。
数字から見る改善の規模
改善前後の主要指標を示す。ページをフレッシュロードしてから入力可能になるまでの時間(75パーセンタイル)は3.1秒から0.55秒へ。Claude Codeの新規セッション開始は0.8秒から0.3秒、Coworkクラウドセッション(Claude for Workのリアルタイム共同作業機能)の読み込みは2.6秒から0.73秒へと短縮された。この改善により、毎日数万ユーザー時間分の待機時間が節約されると試算されている。
きっかけはユーザーからの「遅い」という声だった。チームもそれを認識しており、8月に一本のSlackチャンネルを軸にしたスプリントを立ち上げた。チャンネルの全スレッドにClaudeを参加させ、ボトルネックの発見から実装、デプロイ監視まで担わせる体制を取った。使用したのはClaude Tag(ベータ)と呼ばれる機能で、Slackスレッドに直接Claudeをメンションして会話の流れの中でタスクを依頼できるもの。スプリントで使われた内部研究モデルはAnthropic社内でOpus 5.5相当と位置づけられている。
想定外の発見:em dashが1秒のフリーズを引き起こしていた
このスプリントで最も驚かれた発見の一つが、em dash(—)による構文ハイライトの遅延だ。
CPUのひっかかり(hitch:フレームが突然詰まる現象)を調べていたClaudeが気づいたのは、コードブロックの構文ハイライト時に約1秒のフリーズが発生するケースがあるということだった。原因を辿ると、V8(ChromeやNode.jsが使うJavaScriptエンジン)の文字列処理の仕様に行き着いた。V8はem dashのようにLatin-1の範囲外の文字が含まれると、その文字列全体をUTF-16として保持する。すると構文ハイライトの正規表現処理がすべて低速な2バイトパスを通ることになり、長いコードブロックでは顕著なフリーズとして現れていた。
修正は20行の変更だけだった。コードブロックをハイライト前に1バイト文字列にコピーするだけで問題は解消した。
こうした発見が可能になった背景には、計測の仕組みを根本から変えたことがある。
「計測できた瞬間に最適化が始まる」仕組み
通常のパフォーマンス改善サイクルはこうだ——メトリクスを追加し、データが集まるのを待ち、問題を理解してから着手する。今回はそのサイクルを大幅に短縮した。
鍵になったのが**Valgrind(メモリ・パフォーマンス解析ツール)を使ったJSの命令数カウント**だ。壁時計時間(wall-clock time:実際に経過した時間)はユーザーが実感するものだが、ノイズが多くCIの自動チェックには向かない。node --predictableオプションと組み合わせると決定論的な数値が得られ、PRごとに「何命令増えたか」を正確に比較できる。
Claudeは2つのホットパス(処理が集中する箇所)をValgrindでプロファイリングした。会話のメッセージツリーを組み立てるルーティンと、Claude Codeの出力をスキャンする処理だ。前者では命令の4分の1が「メガモーフィックな辞書ルックアップ」——JavaScriptエンジンの最適化が効かない多態的なオブジェクトアクセスのこと——だと判明し、同じメッセージIDを3回別々に解決していた。修正後、命令数はそれぞれ48%・31%削減、壁時計時間は78%・44%削減された。
さらにCIにラチェット機構を導入した。各ホットパスの命令数上限をチェックインし、超えるPRは自動で落とす。カウントが下がれば日次ジョブが上限値を引き下げる——勝ちは永続し、劣化は即検出される仕組みだ。
他にも連鎖的に発覚した「隠れたコスト」
この計測の網を広げると、既存のメトリクスでは見えていなかった問題が次々と浮かび上がった。
Reactのコンポーザー(入力欄)のタイピングパスには6,900個のフックと900個のストアサブスクリプションが存在し、キー入力のたびに大量の再レンダリングが走っていた。CSSの:root:has()セレクターが1つのDOMアクセスのたびに24ミリ秒を追加していたことも、スタイル再計算の計測で発覚した。
location.reload()の残骸コードが1日50万回の隠れたリロードを引き起こしていたこと、アイドル状態のタブでキャッシュスナップショットが毎分2回メインスレッド上でIndexedDBに書き込まれていたことも見つかった。
最大のUX改善:スタティックコンポーザー
ページ読み込み速度の改善で最もインパクトが大きかったのがスタティックコンポーザーの導入だ。
ReactのHTMLへの静的コピーをほぼ即座に表示し、Reactが初期化されたらその上に直接描画する。ユーザーはReactの初期化を待たずにタイピングを開始でき、入力内容は本物のコンポーザーに引き継がれる。
この仕組みは1ピクセルのズレで破綻するため、複数のガードレールが整備された。jsdomで本物のReactコンポーネントをレンダリングして静的マークアップを生成しテストで乖離を検証する仕組み、14種類のビューポートサイズで静的ページとReactレンダリングを比較して1px以内の一致を保証するテスト、ハンドオフをまたいでキーストロークをタイプしてキー入力の消失・順序入れ替えを検出するテストなどだ。フィールドでは0.1px単位のズレを報告し、ゼロ以外の動きが検出されるとClaudeがスレッドを起票する体制も整えた。
1チャンネル・150スレッドが同時進行
この体制の特徴は水平スケールのしやすさにある。1スレッドのループが機能すれば、スレッドを増やすだけで並列に進められる。1スレッドあたり50〜100件の最適化PRが出ることもあったという。
「このモデルは数字に取り憑かれたやつだ」——エンジニアのShelleyはそう評した。
全員が1チャンネルに集まることで、他チームが変更をレビューに持ち込む文化が自然に生まれ、パフォーマンスを意識したコードが書かれるようになる副次効果もあったと記事は述べている。Claudeを単なる実装補助ではなく、計測・最適化・監視のループを回すエージェントとして位置づけたことが、今回の取り組みの核心だ。
詳細はHow we made claude.ai 3x faster in two weeksを参照していただきたい。