ビルド時間スケーリング計画 (Phase 3-4)

Parky 公開ポータルは Astro 5 の static 出力で運用している。 Phase 2 までは東京中心 (数百ハブ) だったが、全国展開 (Phase 3-1) で ページ数が数万 〜 10 万規模に到達する見込みのため、 ビルド時間が問題になる手前で選択肢を整理しておく。

現在の状況 (2026-04-15)

  • 出力: astro build → Cloudflare Pages static (adapter-cloudflare)
  • 主要な動的ルート:
    • /p/[pref]/[city]/[spot]/ (駅ハブ)
    • /p/[pref]/[city]/[spot]/[filter]/ (属性フィルタ 5 種)
    • /spot/[id]/ (駐車場詳細)
    • /scene/[sceneSlug]/ (4 シーン)
    • /media/[slug]/ (MDX)
  • 主要なビルド時 DB アクセス:
    • fetchPublishableStationHubs → 1 回
    • fetchParkingListForStationHub(stationId) → 駅ハブ数 × 1 回
    • fetchReviewIndexByLot → 1 回 (全 approved レビューを Map に)
    • fetchAllParkingLotIds → 1 回 (pagination)
  • Phase 2-1 リファクタで上記は全てモジュール単位 Promise キャッシュで重複排除済み

計測トリガー

まず計測から始める。以下のタイミングで build 時間を記録:

  • 現在 (東京のみ) の build 時間
  • kanagawa 解禁後
  • osaka 解禁後
  • 初の 4 都市同時解禁時

astro build 末尾の build 7 page(s) built in 2.07s を GitHub Actions の ログから追うだけで十分。閾値は下記:

  • 5 分未満: 何もしない (ISR 不要、Vercel 無料枠)
  • 5〜15 分: 分割ビルド検討
  • 15 分超: ISR / on-demand revalidation に移行

最適化オプション

Option A: 地域分割ビルド (推奨の第一歩)

PUBLIC_PUBLISHED_PREFECTURES を 複数の workflow に分けて回す。 例:

  • deploy-public-prod-kanto.yml → tokyo,kanagawa,saitama,chiba
  • deploy-public-prod-kansai.yml → osaka,kyoto,hyogo,nara
  • etc.

それぞれ別の Vercel プロジェクト (サブディレクトリビルド) or 同一プロジェクトに対して rsync 差分反映。

  • 利点: 既存コード無変更。env だけで制御できる
  • 欠点: sitemap をマージする手間、Vercel 側で分割デプロイが面倒
  • 実装: Phase 3-1 の仕組みを流用、新 workflow を追加するだけ

Option B: Vercel ISR (on-demand revalidation)

output: 'hybrid' に切替、動的ルートのみ ISR 化。 Supabase 側の更新 webhook から revalidatePath() を呼び出して 該当ページだけ再生成する。

  • 利点: ビルド時間が劇的に短縮 (初回だけ build、以降は差分)
  • 欠点: 複雑度増加、Vercel Pro プラン相当のリソース要
  • 前提: adapter を vercel のまま使えるが、static export の恩恵を 一部手放す (キャッシュヒット率で相殺)

Option C: 差分ビルド (incremental)

Astro 自体は incremental build をサポートしない。 代替: .vercel/output/static/p/{pref}/ 単位で前回成果物を保持し、 対象地域のみ再ビルド + rsync 差分アップロード。

  • 利点: Option B より単純
  • 欠点: sitemap / hreflang の整合性管理が手作業
  • 使い所: Option A で破綻してから検討

Option D: DB 側の集計化

現状は各ハブのページ body で fetchParkingListForStationHub を呼んでいる。 このクエリが N 回走ることが支配的になったら、 ハブ単位の JSON 集計カラム (hub_content JSONB) を MV / cron で 1 度だけ生成しておき、build 時はそれを SELECT するだけにする。

  • 利点: ネットワーク往復を 1 本に圧縮
  • 欠点: MV 管理とスキーマ複雑化
  • 前提: Phase 3-1 の in-memory cache で十分か確認した上で検討

推奨プラン

  1. まず計測: GitHub Actions ログで build 時間を記録
  2. 5 分超えたら Option A (地域分割) を導入
  3. Option A で耐えきれなくなったら Option D (JSON 集計) を入れる
  4. Option D でも 15 分を超えるようになったら Option B (ISR) に 移行検討

コード変更は Phase 3 段階では不要。本ドキュメントは「問題化したとき すぐ動ける」ための設計メモ。

↗ Source markdown (build-time-scaling.md)