mcmaster-fast は何をしますか?
他のサイトを mcmaster.com のようにする:初回ペイントは数十ミリ秒、次のページは URL バーが更新される前に表示されます。
スタックは問いません。McMaster は ASP.NET、YUI、ScriptCombiner でこれを実現しています。重要なのはリクエストの順序と数であり、フレームワークの流行ではありません。
実際に行っていること
実サイト (2026-09-13) と Wes Bos の分解レポート (klinke.studio ノート) から観察:
| レイヤー | McMaster の動作 | なぜ一瞬に感じるか |
|---|---|---|
| 初回バイト | サーバーレンダリング HTML。ブラウザは JS の前に描画。ウォームシェルで FCP ~64ms、TTFB ~19ms。 | ユーザーはバンドルを待つスピナーではなく、ページを目にする。 |
| シェル | #ShellLayout_Cntnr + #MainContent。ヘッダー/カートはマウントされたまま。history.pushState。 | カテゴリクリックで同一ヘッダーノードを維持し、コンテンツを 35ms で入れ替え。 |
| 予測 | ホバー/意図により、クリック前に次の HTML を取得。 | クリックはキャッシュヒット+DOM スワップ。 |
| 再訪問 | サービスワーカーが GET ナビゲーション (PDF 以外) をキャッシュファースト。初回ロード後に / をキャッシュ。 | オリジン HTML は ~200ms (mc-turn);SW がローカルから配信。 |
| ウォーターフォール | 画像ホストの dns-prefetch。woff2 フォント、ロゴ、LCP スプライト、ページ JS/CSS、ShellDynamic.aspx を preload。 | ブラウザは CSS で発見する前にフォント/LCP を開始。 |
| CSS | ~32KB の共通 CSS を <head> 内の <style> にインライン化。残りはページ固有のコンバイナ経由。 | 初回レイアウトに追加の CSS リクエスト不要。 |
| JS | ページ固有の ScriptCombiner バンドル (?files=…)。非同期。WebParts はペイント後にロード。 | カタログページはチェックアウトコードをダウンロードしない。 |
| アセット | バージョン付き URL (/mv1789156784/、?ver=)。Cache-Control: public,immutable,max-age=31536000。画像ホスト images1.mcmaster.com。タイルグリッド用スプライト。 | 年間キャッシュ、無効化の手間なし、リクエスト数わずか。 |
| 安定性 | 予約済みボックス/スプライト。CLS 0 を測定。 | 画像到着時のリフローなし。 |
| ウェイト | ファーストパーティ分析 (/trk/)。広告なし。CSP は *.mcmaster.com に制限。 | ページが製品そのもの。 |
HTML ドキュメント自体は Cache-Control: no-cache かつ Akamai で x-check-cacheable: NO です。「すべての HTML を CDN キャッシュ」をコピーしないでください。彼らはブラウザ内でシェルをキャッシュし、イミュータブルな静的ファイルをエッジでキャッシュしています。
優先順位ラダー
ウォームキャッシュで LCP が ~200ms 以下になる最初の段で止めてください。1 つの PR で Workbox、スプライトパイプライン、かつ 投機ルールを導入しないでください。
- ブラウザが描画できる HTML を配信する。 SSR または静的 HTML。最初のビューをクライアントのみでレンダリングしない。最初の画面を構築する JS を削除する。
- 初回ペイントのブロックを解除する。 画面内の CSS のみをインライン化 (または 1 つの小さなブロッキングシート)。LCP 画像と woff2 フォント (
crossorigin) をpreloadする。すべての画像にwidth/height(または CSS aspect-ratio) を付ける。 - イミュータブルな静的ファイル。 フィンガープリントまたはバージョンクエリ。
Cache-Control: public, immutable, max-age=31536000。 - 永続的なクローム+コンテンツスワップ。 共有レイアウト。次のナビゲーションは 1 つのコンテンツノードを置き換え、
pushStateする。ヘッダーを再マウントしない。 - 意図先読み。 ホバー/ビューポートで次のドキュメントを投機的に取得。上限を設定する。チェックアウト、検索 API、認証済み HTML は決して先読みしない。
- ナビゲーション SW (オプション)。 公開シェル/ホームの GET ナビゲーションをキャッシュファーストで処理。デプロイ時にクリア。ページ側から無効化し、巧妙な SW は使わない。サイトがほとんど非公開の場合はスキップ。
- ページ固有 JS。 ルート分割。分析はアイドル時まで遅延。製品でないサードパーティタグは削除する。
- スプライト/画像ホスト は、一画面に何十もの小さなアイコンがある場合のみ。HTTP/2 +数枚の圧縮画像で十分。
エージェントワークフロー
サイトをこの方法で高速化するよう依頼された場合:
- 実際の初回ロードとアプリ内ナビゲーション 1 回をトレース (ネットワーク+描画されるもの)。現在の LCP 要素とそれをブロックする JS を特定する。
- 不足しているラダーの最下位を適用する。ユーザーが一括適用を依頼した場合を除き、1 パスにつき 1 つの変更。
- 新しいライブラリではなく、リポジトリにあるプラットフォーム機能 (Next
<Link>、next/font、App Router レイアウト) を優先する。 - パスの後、1 つのチェックを残す: LCP / FCP 数値、またはクライアントナビゲーションでシェルノードが再利用されたことを確認する小さなアサート。
- techniques.md を読んで、実装するラングの正確なレシピを確認する。recipes.md を読んで、Next.js / バニラ / 既存 SPA のマッピングを確認する。
厳格なルール
- HTML が製品である。JS はオプションの拡張。
- 先読みはヒントであり、クローラーではない。同オリジンの GET ドキュメントのみ。
- パーソナライズされた HTML は
no-storeか、短い TTL で SW のみ。カート/アカウントの HTML を共有 CDN キャッシュに絶対に置かない。 - すべてのアセットをインターセプトするサービスワーカーを追加しない。McMaster の
ServiceWorkerJS.aspxに合わせ、ナビゲーションドキュメントのみ。 - YUI、スプライト、ASP.NET をコピーしない。操作順序をコピーする。
- 高速な HTML ページを修正としてクライアント SPA に「モダナイズ」しない。
- サードパーティスクリプト(広告、タグマネージャー、チャット)は有罪とみなす。初回ペイントから除外するか、削除する。
- 価値の低いラングをスキップした場合は
ponytail:でマークする。
完了条件
- 初回訪問: アプリバンドルが実行される前に HTML が描画される。LCP はクライアントレンダリングではなく、サーバー送信要素である。
- 次のクリック: クロームはマウントされたまま;コンテンツ領域のみがスワップされる。
- ホーム/シェルの再訪問: ローカルまたはメモリキャッシュから配信される。
- フォントと LCP 画像が最初の 1~2 ラウンドトリップ内にあり、CSS 発見後に発見されるのではない。
- 変更したページで CLS が 0 付近を維持する。