Astroビルドが10分に遅くなった3つの原因と高速化手順|caffeinate・画像キャッシュ永続化・事前計算
作成日:

Astroビルドが10分に遅くなった3つの原因と高速化手順|caffeinate・画像キャッシュ永続化・事前計算


論旨

64GB メモリから切り出した 16GB の RAMDisk(メモリ上の超高速仮想ディスク)へ出力先とキャッシュを直結し、以前は 17 秒〜 30 秒前後 で軽快に終わっていた Astro の本番ビルドが、ある日ふと時計を見ると 10 分 35 秒(635.80 秒) もかかるようになっていました。「RAMDisk の設定が外れたのか?」「記事が増えて限界が来たのか?」と過去の全ビルド生ログを 1 秒単位で突き合わせてみたところ、思いもよらない 3 つの真犯人 が重なっていたことが判明しました。

結論からお伝えすると、急激な遅延の正体は 「①バックグラウンド処理中の Mac 省電力スリープ(+576 秒)」「②再起動による RAMDisk 上の最適化 WebP 画像キャッシュ 3,766 枚の揮発」「③公開 600 記事規模で顕在化した getCollection 重複ループと重複サムネイル生成」 の 3 点であり、これらを順番に潰したことで 静的ルート生成は 15.46 秒 → 6.92 秒へ 55.2% 短縮、派生画像は 595 枚削減され、総 2,214 ページのビルドが 45.10 秒 で安定完走するようになりました。本記事では、原因の特定プロセスから安全な実装コードまで余さず共有します。

合わせて読みたい深まる関連情報
対象となる方
  • Astro で記事数が 数百本〜数千ページ規模 に増え、astro build の待ち時間がじわじわ伸びて困っている方

  • AI エディタやターミナルでバックグラウンドビルドを走らせた際、ときどき異常に長い時間(5 分〜 10 分以上)がかかる現象 に遭遇している方

  • Mac の RAMDisk にビルドキャッシュを置いている ものの、OS 再起動後の初回ビルドで毎回待たされるストレスをなくしたい方

なぜ30秒のビルドが10分35秒に激増したのか

生ログに刻まれた576秒の空白と3つの犯人

「なんだか最近ビルドが遅い気がする」と感じたとき、勘だけで設定ファイルをいじり始めると泥沼にハマります。まずは過去のタスク実行ログに残っていた astro build のタイムスタンプを掘り起こし、10 月中旬(約 30 秒以内だった頃)と直近のビルドを並べて比較してみました。

すると、「10 分 35 秒(635.80s)かかった回」 の生ログに、決定的な瞬間が記録されていたのです。

18:56:40 ▶ src/pages/rss.xml.js
19:06:16 └─ /rss.xml (+576.16s)
...
19:06:20 [build] 2214 page(s) built in 635.80s

なんと、18:56:40 に RSS フィード(/rss.xml)の生成に入った直後から、19:06:16 に完了行が出るまで ぴったり 576.16 秒(9 分 36 秒)も時計がワープ していました。ちなみに別の回(20:15 実行分)のログを見ると、同じ /rss.xml はわずか +97ms(0.097 秒) で一瞬のうちに終わっています。

質問するおじさん

わしゃこのログを見た瞬間、てっきり /rss.xml を作るプログラムが無限ループか通信待ちで 10 分近く暴走しとるんかと思うたわい!

解説ナビゲーター

ログの文字列だけ見ると RSS 生成が犯人にしか見えませんよね!でも CPU が本当に 10 分間フル回転していたのではなく、AI エディタにデプロイを任せて画面から手を離していた隙に Mac 本体が省電力のアイドルスリープに落ちてしまい、約 9 分半後に目を覚ましただけ だったんです。

つまり、635.80 秒 からスリープしていた 576.16 秒 を差し引くと、実質的なビルド稼働時間は 約 59 秒 でした。RAMDisk のマウント自体は正常に効いており、directory: /Volumes/RAMDisk/$USER/astro-dist/ へのメモリ直書きも壊れていなかったことが裏付けられました。

放置すると毎回遅くなる構造的な2つの罠

しかし、「なーんだ、Mac が寝ていただけか!」で終わらせてはいけません。生ログをさらに詳しく並べてみると、スリープ以外にも 「再起動直後に必ず 10 分コースになる罠」 と 「平常時でも 17 秒 → 56 秒へ 3 倍以上に膨らんでいた構造的なボトルネック」 の 2 つが隠れていたのです。

計測タイミング総ページ数派生WebP画像数Viteバンドル静的ルート生成合計ビルド時間
10月中旬(約380記事)1,412 ページ約 620 枚7.20 秒8.82 秒17.42 秒
直近・スリープ発生回2,214 ページ3,766 枚35.12 秒595.8 秒(睡眠込)635.80 秒(10分35秒)
直近・平常稼働回(改修前)2,214 ページ3,766 枚33.17 秒15.46 秒56.21 秒

記事数が約 380 本から 約 600 本(タグ・カテゴリ等を含め総 2,214 ページ) へ成長し、写真たっぷりの実機レビュー記事が増えたことで最適化対象の WebP 画像も 620 枚 → 3,766 枚(約 6 倍) に増えていました。ここに以下 3 つの問題が重なっていたのが真相です。

Astroビルドを10分へ鈍化させていた3重の遅延メカニズム
要因 1
OS省電力スリープ

画面放置中にMacがアイドル睡眠へ入り、バックグラウンドのビルドが9分半も一時停止。

要因 2
RAMDisk画像揮発

Mac再起動でメモリ上のWebPキャッシュ3,766枚が消滅し、初回に数分〜10分の全再変換が発生。

要因 3
重複ループと画像倍増

レイアウト内のgetCollectionが600回走り、一覧用の別サイズWebPも595枚余分に生成。

単発のOSスリープに加え、キャッシュ揮発とO(N²)ループが重なっていました

原因が 1 ミリの曇りもなく特定できれば、あとは上から順番に急所を潰していくだけです。実際に行った 3 つの対策を見ていきましょう。


対策その一:caffeinateでスリープを遮断

バックグラウンド実行中にCPUが寝る仕組み

最近の AI コーディング環境では、ビルドやテスト、サーバーへの rsync 転送まで一連のコマンドをバックグラウンドで走らせ、人間はその間にコーヒーを淹れたり別の資料を読んだりすることが増えています。

ところが macOS の電源管理デーモン(powerd)は、キーボードやマウスの入力が一定時間途絶えてディスプレイが暗転すると、ターミナルの裏で Node.js(astro build)が計算中であっても 「ユーザー操作がないためシステム全体を省電力スリープへ移行してよい」 と判定してしまうことがあります(Intel Mac・Apple Silicon 共通で、省電力設定や外部モニター消灯連動のタイミングによって発生します)。

標準コマンド1行でビルド中だけ起こす設定

これを防ぐために「常駐型のスリープ防止アプリを入れて Mac を 24 時間ずっと起こしっぱなしにする」のは電気代もモニター寿命ももったいないですよね。一番スマートなのは、macOS に最初から標準搭載されている /usr/bin/caffeinate コマンド でビルドコマンドだけを包む方法です。

package.json のビルドスクリプトを、次のように 1 箇所書き換えるだけで完了します。

{
  "scripts": {
    "build": "/usr/bin/caffeinate -i astro build"
  }
}
☕ caffeinate -i で包む方式の3つのメリット
  1. ビルド中の数十秒間だけピンポイントでスリープを遮断 : -i(アイドルスリープ防止)オプションを付けてコマンドを渡すと、astro build のプロセスが動いている間だけ OS に「今計算中だから寝ないで!」という電源アサーション(ロック)を発行してくれます。

  2. 正常終了でもエラー停止でも自動でロック解除 : caffeinate は子プロセス(astro build)のプロセス ID(PID)を直接監視しているため、ビルドが完了した瞬間はもちろん、万が一構文エラー等で途中終了した場合でも 即座に通常の省電力モードへ自動で戻ります(永久にスリープしなくなる心配はありません)。

  3. 画面の消灯は邪魔しない(パネル保護と省電力) : -d(ディスプレイ消灯防止)ではなく -i(システムアイドルスリープ防止) を選んでいるため、離席中にモニター画面が暗くなっても CPU とメモリ上のビルド処理だけは一切止まらずに完走します。

質問するおばさん

これなら新しいアプリを何もインストールしなくていいし、ビルドが終わったらちゃんと普段通りスリープしてくれるから安心ね!ところで、よく見かける NODE_OPTIONS=--max_old_space_size=16384 も一緒に付けていいの?

解説ナビゲーター

そこは搭載メモリ量に合わせて調整するのが鉄則です!16384(16GB)は 物理メモリ 64GB 以上 を積んでいる Mac 向けの余裕設定なので、もしメモリ 16GB の Mac でそのまま真似すると OS スワップが発生して逆に遅くなります。16GB 機なら 4096(4GB)、32GB 機なら 8192(8GB)程度に留めておくのが快適ですよ。


対策その二:RAMDisk画像キャッシュの永続化

再起動でWebP画像3千枚が消える揮発の罠

2 つ目の対策は、「Mac を再起動した直後の初回ビルドだけ猛烈に遅くなる問題」 の解消です。

当サイトでは SSD の寿命(TBW)を守りつつ I/O を高速化するため、astro.config.mjs でキャッシュ保存先(cacheDir)を /Volumes/RAMDisk/$USER/astro-cache に指定しています。普段はメモリ上に変換済みの WebP 画像キャッシュが残っているため、3,000 枚以上の画像があっても (reused cache entry) と表示されて わずか 0.5 秒〜 0.7 秒 で画像ステップを通過します。

しかし、RAMDisk は揮発性メモリです。OS アップデートやメンテナンスで Mac を再起動すると、/Volumes/RAMDisk/$USER/astro-cache の中身はきれいに消えてしまいます。記事が 100 本の頃は再生成も数十秒で済みましたが、3,700 枚超の写真を Sharp で一から WebP 圧縮し直すとなると、再起動後の 1 回目だけ数分〜 10 分コース に逆戻りしてしまいます。

ビルド中を避ける5分周期退避と起動時復元

そこで、すでに 5 分おきにバックグラウンドで動かしている定期同期スクリプト(sync_brain.sh)と、ログイン時の RAMDisk 構築スクリプト(create_ramdisk.sh)に astro-cache の SSD 自動退避&起動時リストア を組み込みました。

RAMDiskの爆速I/Oと再起動耐性を両立する2層キャッシュ構成
/Volumes/RAMDisk/$USER/astro-cache

astro build が直接読み書きする超高速領域。ログイン直後に Layer 2 から自動復元されるため、再起動後の初回ビルドも 0.5 秒でキャッシュヒットします。

$HOME/.gemini/antigravity/astro_cache_backup

launchd が 5 分周期で rsync -a --delete 差分同期する実体フォルダ。画像が増えた時だけ数枚分の差分が書き込まれるため SSD 摩耗もほぼゼロです。

普段の読み書きは100%メモリ上で完結させ、変更差分だけを5分周期でSSDへ静かに控え保存します

ここで「急がば回れ」の設計として必ず入れておくべきなのが、3 つのエッジケース(境界条件)を防ぐ安全ガード です。

# 1. 定期同期側(sync_brain.sh:5分周期)
RAM_ASTRO_CACHE="/Volumes/RAMDisk/$USER/astro-cache"
BACKUP_ASTRO_CACHE="$HOME/.gemini/antigravity/astro_cache_backup"

# ガード①:assetsフォルダが実在かつ非空であり、ガード②:astro build 実行中でない時のみ同期
if [ -d "$RAM_ASTRO_CACHE/assets" ] && [ -n "$(ls -A "$RAM_ASTRO_CACHE/assets" 2>/dev/null)" ]; then
    if ! pgrep -f "astro build" >/dev/null 2>&1; then
        mkdir -p "$BACKUP_ASTRO_CACHE"
        rsync -a --delete "$RAM_ASTRO_CACHE/" "$BACKUP_ASTRO_CACHE/"
    fi
fi
# 2. ログイン起動側(create_ramdisk.sh:RAMDisk作成直後)
mkdir -p "$USER_MOUNT_PATH/astro-cache"
if [ -d "$HOME/.gemini/antigravity/astro_cache_backup" ] && [ -z "$(ls -A "$USER_MOUNT_PATH/astro-cache" 2>/dev/null)" ]; then
    rsync -a "$HOME/.gemini/antigravity/astro_cache_backup/" "$USER_MOUNT_PATH/astro-cache/"
fi
🛡️ キャッシュ破損とゾンビ復活を防ぐ3重ロック
  1. 空ディレクトリによる誤消去防止 : rsync --delete を使う際、もし RAMDisk 側が空っぽの状態で同期が走ると SSD 側の大切なバックアップまで全消去されてしまいます。必ず astro-cache/assets の中身が空でないことを確認してから同期します。

  2. ビルド実行中の競合スキップ : astro build がまさに画像を書き出している最中に rsync が走ると、書きかけの半端なファイルが退避される恐れがあります。! pgrep -f "astro build" でビルド非実行時のみ静かに同期させます。

  3. 明示的キャッシュクリア時の連動消去 : トラブル切り分けのために手動で npm run キャッシュクリア を実行した際は、RAMDisk 上の astro-cache だけでなく SSD 側の astro_cache_backup も同時に削除 するよう package.json に組み込み、次回再起動時に古いキャッシュがゾンビ復活する不整合を防ぎます。


対策その三:重複ループと派生画像の徹底削減

レイアウト内のコレクション取得600回を撤廃

スリープと再起動の罠を塞いだら、最後は 「平常時のビルド自体をさらに速く、軽くする」 コード最適化です。ログを分析すると、generating static routes(全記事の HTML 生成フェーズ)だけで 15.46 秒 かかっていました。

犯人を探ると、記事用のレイアウトコンポーネント(BlogPost.astro 等)のフロントマター内に、記事末尾の「次の記事へ進む」リンクを求めるためのこんな処理が入っていました。

// ❌ 改修前:各記事ページのレンダリングごとに毎回コレクション全件を取得・ソートしていた
const allPosts = await getCollection("blog");
const categoryPosts = allPosts.filter(/* 公開判定・カテゴリ抽出 */).sort(/* 日付・優先度ソート */);

記事が 50 本や 100 本のうちはまったく気になりません。しかし公開記事が 約 600 本 になると、1 記事をレンダリングするたびに 600 件のフィルタリングとソートが走り、全体で 600 記事 × 600 件 = 約 36 万回(計算量 O(N^2)) もの重複ループが毎ビルド実行されていたのです!

これを解消するため、動的ルートを生成する親ファイル(src/pages/blog/[...slug].astro)の getStaticPaths() 内で全カテゴリーの並び順と前後リンクをたった 1 回だけ事前計算 し、各レイアウトへ precomputedNav props として渡す設計へ変更しました。

// ✅ 改修後:[...slug].astro の getStaticPaths() 内で 1 回だけ事前計算して props で渡す
export interface PrecomputedReviewNav {
  nextPostLink: string | null;
  nextPostTitle: string;
  isLoopToFirst: boolean;
}

// カテゴリー別のソート済み配列を 1 回だけ構築し、O(1)〜O(N) で全記事の次リンクを確定!
// レイアウト側(BlogPost.astro)は precomputedNav が渡されたら getCollection("blog") を完全スキップ

もちろん、将来別の固定ページ等から precomputedNav なしでレイアウトが直接呼ばれた場合でも壊れないよう、未指定時のみ従来の getCollection が動く後方互換フォールバックを残しています。

一覧と記事本番の画像幅を揃えて595枚削減

さらに画像生成ログ(3,766 枚)の内訳を調べていて、もう一つの見落としに気づきました。

  • 個別記事ページ(BlogPost.astro 等)のアイキャッチ画像 : 元画像を超えない範囲で最大 640×420px に収まる width={heroWidth}(format="webp", quality={80})を指定
  • 全記事一覧ページ(/blog/index.astro)のカード画像 : 固定で width={720} height={360} を指定

なんと、一覧ページと個別記事ページで指定ピクセル幅が微妙に違っていたせいで、全 595 記事すべてのアイキャッチ画像について「一覧ページ専用の 720×360 版 WebP」と「記事本番用の 640 幅版 WebP」の 2 種類が二重に生成・転送されていた のです。

そこで全記事一覧ページ側の <Image> 指定も、記事本番と 1 ピクセルの狂いもなく完全同一の width={heroWidth}・format="webp"・quality={80} に統一しました。

質問するおじさん

ちょっと待った!一覧ページの <Image> から height={360} を外して横幅指定だけにしたら、カードの縦横比がバラバラになったり、読み込み中に画面がガタッとズレたり(CLS 悪化)せんのかいの?

解説ナビゲーター

いいところに気づかれましたね!実は Astro の <Image> コンポーネントは width さえ渡せば元画像の比率から正確な width・height 属性を HTML の <img> タグへ自動出力してくれます。さらに一覧カードの CSS 側に aspect-ratio: 2 / 1; object-fit: cover; が効いているため、画像ロード前から 2:1 の枠サイズが完全に固定されてレイアウトズレ(CLS)はゼロ のまま、見た目も一切変わりません!

しかもこの統一には、ビルド時間の短縮以上に嬉しい 読者体験(UX)の副産物 があります。読者が「全記事一覧ページ」で目当ての記事カードをクリックして個別記事ページへ遷移した瞬間、まったく同じ URL(ハッシュ名)の WebP 画像がすでにブラウザキャッシュに入っているため、アイキャッチ画像の再ダウンロード通信がゼロになり 0 秒でパッと表示される ようになったのです。


実測比較:2214ページが45秒で安定完走

改修ビフォーアフターの全フェーズ計測表

対策 1・2・3 をすべて反映し、実際に本番ビルド&デプロイを走らせた生ログの計測結果がこちらです。

検証項目改修前改修後(実測値)改善結果
省電力スリープ発生時635.80 秒(10分35秒)発生ゼロ(物理遮断)caffeinate -i で離席中のビルド停止を根絶
Mac再起動後の初回ビルド数分〜 10 分(全画像再変換)約 45 秒(即時リストア)SSD astro_cache_backup から起動時に自動復元
静的ルート生成時間15.46 秒6.92 秒55.2% 短縮(-8.54 秒)
最適化WebP画像の総枚数3,766 枚(710ms)3,171 枚(476ms)重複サムネイル 595 枚をぴったり削減
Viteバンドル時間33.17 秒29.99 秒約 3.2 秒短縮(600 本近い MDX 変換)
平常時トータルビルド56.21 秒45.10 秒11.11 秒短縮(2,214 ページ完走)

ログ上でも (3171/3171) ✓ Completed in 476ms. と記録され、公開 595 記事分の重複アイキャッチ画像(3,766 - 3,171 = 595 枚)が計算通り 1 枚の誤差もなく綺麗に消え去りました。静的ルート生成も 15.46 秒から 6.92 秒へと半分以下 に縮まり、サイトマップ生成まで含めた全 2,214 ページが 45.10 秒 で安定して駆け抜けるようになっています。

質問するおばさん

ルート生成が 6 秒台になってすごく速くなったわね!残りの Vite バンドル時間(約 30 秒)はそのまま残しておいて大丈夫なの?

解説ナビゲーター

はい、この約 30 秒は 600 本近い MDX 記事(カスタム図解や数式コンポーネント入り)をバンドルし、PageSpeed 高速化のために全ページの CSS インライン化(inlineStylesheets: 'always')を並列実行している正当なコンパイル時間です。ここを無理に削ろうとして動的サーバー化(SSR)や複雑な分割を入れると、今度は静的 HTML ならではの「表示爆速・サーバー負荷ゼロ・セキュリティ無敵」という最大の強みが損なわれるため、45 秒で完全静的ビルド+差分転送が終わる今の構成がベストバランス なんです。

ノルウェージャンフォレストキャット

10 分待たされていたのが 45 秒で終わって、しかもビルド中に画面が消えてもサボらず最後まで走ってくれるなら大満足にゃ〜。

大容量64GBメモリと高速SSDが支える快適さ

今回のように astro-cache(数千枚の最適化 WebP)・vite-cache・astro-dist(2,200 ページ超の完成 HTML 群)をすべて 16GB の RAMDisk 上に載せ、さらに Node.js に余裕あるヒープメモリを与えて並列ビルドを回し切る うえで、土台となっているのが 64GB の大容量物理メモリ と バックアップ受け皿となる高速 SSD です。

推論(試算)ですが、64GB メモリ環境や高速ポータブル SSD の構築に 10 万〜 15 万円前後の投資を行ったとしても、毎日ブログ執筆や個人開発で使う母艦として 5 年間(約 1,825 日)使い倒せば 1 日あたりの快適コストは約 55 円〜 82 円 に収まります。ビルドのたびに内蔵 SSD の寿命(TBW)をゴリゴリ削ったり、再起動のたびに 10 分間画面の前で待たされたりする無駄な時間がゼロになることを考えれば、元が取れてお釣りがくる投資です。

これから現行の Apple シリコン搭載 Mac で同じく 64GB メモリ+ RAMDisk の快適ビルド母艦を組む場合は、後からメモリを増設できないユニファイドメモリ構造のため、最初から 64GB 構成を選べる Pro チップ搭載の Mac mini が最もコストと性能のバランスに優れています。

Apple Mac mini(M4 Pro 等 Appleシリコン Pro系チップ・64GBユニファイドメモリ構成)

Apple Mac mini(M4 Pro 等 Appleシリコン Pro系チップ・64GBユニファイドメモリ構成)

一方、「広大な 27 インチ 5K Retina 画面で記事執筆とプレビューを並べたい」「初期コストを抑えつつ自分でメモリを 64GB〜 128GB へ増設したい」という方には、背面のメモリスロット扉から工具なしで DDR4 SO-DIMM を増設できる Intel 最終世代の iMac 27 インチ(2020 年モデル)と Crucial 製メモリの組み合わせが、静的サイト開発や AI 壁打ち母艦として今なお高い実用性を誇ります。

【中古・整備済品】Apple iMac 27インチ Retina 5K (2020年モデル / Intel最終世代・メモリ自己増設対応)

【中古・整備済品】Apple iMac 27インチ Retina 5K (2020年モデル / Intel最終世代・メモリ自己増設対応)

【Intel Mac増設用】Crucial iMac 27インチ(2019/2020)・ノートPC用 メモリ DDR4-2666 SO-DIMM (16GB×2 / 32GB×2)

【Intel Mac増設用】Crucial iMac 27インチ(2019/2020)・ノートPC用 メモリ DDR4-2666 SO-DIMM (16GB×2 / 32GB×2)

また、astro-cache の 5 分周期バックアップや過去の AI 対話アーカイブ、Time Machine バックアップを熱ダレなく高速(毎秒 2,500〜 3,000MB クラス)に受け止める外付けストレージとしては、放熱性の高いアルミ筐体を採用した Thunderbolt 3 / USB 両対応のポータブル SSD を 1 台繋いでおくと安心です。

SanDisk Professional PRO-G40 SSD 4TB / 2TB (Thunderbolt 3 & USB 3.2 Gen 2 両対応)

SanDisk Professional PRO-G40 SSD 4TB / 2TB (Thunderbolt 3 & USB 3.2 Gen 2 両対応)


まとめ:AIにログを読ませてボトルネックを潰そう

「以前よりビルドが遅くなった気がする」と感じたときは、当てずっぽうでキャッシュを消したり設定を書き換えたりする前に、まず実際のビルドログを時系列で並べて「どのフェーズで何秒食っているのか」を数字で切り分けること が解決への一番の近道です。「caffeinate -i によるスリープ遮断」「RAMDisk 画像キャッシュの SSD 永続化リストア」「getStaticPaths での一括事前計算と画像サイズ統一」の 3 点セットを入れておけば、記事が 600 本・数千ページ規模へ育っても、再起動直後から毎回サクッと数十秒で本番デプロイを完結できます。

✅ 本構成で幸せになる人・向かない人
  • 導入して幸せになる人 : Astro で 100 記事〜数百記事規模のブログ・メディアを育てており、Mac ローカルビルドの待ち時間や再起動後の画像再変換ストレスを根本からなくしたい方

  • 別の選択肢が向く人 : 記事数がまだ 10〜 30 本程度でビルドが数秒で終わっている方や、手元の Mac ではなくクラウド側(Cloudflare Pages / Vercel 等)のみでビルドを完結させている方(ただし getCollection の事前計算と画像サイズ統一はクラウドビルドの分数節約にもそのまま効きます!)

ご自身の Astro プロジェクトでも「どこがビルドのボトルネックになっているか診断し、安全に高速化したい」という方は、以下のプロンプトをコピーして AI エディタへ貼り付けてみてください。

🤖 自分の環境に合わせてAIに高速化させるコピペ用プロンプト

※レイアウト間の props 受け渡し変更や RAMDisk バックアップの rsync --delete 制御は、条件を 1 つ誤るとリンク切れやキャッシュ消失を招きます。軽量モデルではなく、必ず 『Gemini 4 Argon』(または同等以上の最上位推論モデル)を選択して実行させてください。

以下の記事の検証手順を参考に、私の Astro プロジェクトのビルド時間を計測・分析し、安全に高速化したいです。
参照URL: https://lab.chihouzakki.com/blog/review/astro-build-10min-slow-caffeinate-ramdisk-cache-getcollection/

【絶対厳守ルール】
1. いきなりコードを書き換えたりキャッシュを削除したりせず、まず現在の package.json、astro.config.*、動的ルート([...slug].astro 等)、記事レイアウト、一覧ページの <Image> 指定を調査し、フェーズ別のボトルネック診断と修正計画を提示して私の合意を得てください。
2. 私の Mac の搭載メモリ容量(sysctl hw.memsize)と RAMDisk の有無を確認し、NODE_OPTIONS のヒープ上限やキャッシュ永続化の要否を私の実機スペックに合わせて提案してください。
3. 以下の3点を重点チェックしてください:
   - macOS 環境でのビルド中アイドルスリープ防止(/usr/bin/caffeinate -i の適用)
   - 各ページ・レイアウト内で getCollection() が記事数分ループ実行(O(N²)化)していないか(該当する場合は getStaticPaths での 1 回事前計算+フォールバック維持へ改善)
   - 一覧ページと個別記事ページで同一アイキャッチ画像から別サイズの派生 WebP が重複生成されていないか(CSS の aspect-ratio / object-fit で見た目を維持したまま生成幅を統一できるか)
4. 実装前には対象ファイルのバックアップを取り、改修前後のビルド秒数・生成画像枚数の実測比較を報告してください。

毎日の執筆とデプロイの引っかかりをひとつずつ丁寧に取り除いて、記事が何百本に増えても軽快に走り続ける心地よい発信基地を育てていきましょう!

高速ビルドが45秒で終わって安心してお昼寝するノルウェージャンフォレストキャット

▲ 人間がお昼寝していても Mac は寝落ちせず 45 秒できっちり仕事を終わらせてくれるにゃ