静的サイトジェネレーター(SSG)は、運用コストの低さと高速な配信が最大の魅力です。しかし、コンテンツが積み重なり、管理するファイル数が膨大に膨れ上がると、これまで見えてこなかった「ビルドとデプロイの長期化」という壁にぶつかります。
1ページあたりの処理時間はわずか数ミリ秒の差であっても、全ページを合算すれば数分、あるいは数十分のロスに繋がります。このロスの蓄積は、単に待ち時間が増えるだけでなく、サーバー負荷の増大や転送エラー(タイムアウト)を招く深刻な問題です。
今回は、限られたサーバー資源を有効活用しつつ、肥大化したプロジェクトのデプロイ時間を劇的に改善するために行った、具体的なテンプレート最適化の手法を紹介します。
1. 処理の共通化と再利用(partialCached)
大規模なサイトでは、同じパーツを何度も再生成することが最大のボトルネックになります。これを「一度計算したら使い回す」設計にシフトしました。
- グローバルキャッシュの導入
- フッターやナビゲーションなど、全ページで内容が同一のコンポーネントを
partialCachedに移行。 - 特に外部RSSの取得や画像パスの解決など、重い処理を伴うパーツを「サイト全体で1回」の実行に抑え込みました。
- フッターやナビゲーションなど、全ページで内容が同一のコンポーネントを
- スコープを絞ったキャッシュ
- 記事一覧のサムネイル生成など、ページごとに固有の処理が必要なものは、識別子(パス等)をキーにしてキャッシュを分離。
{{ partialCached "thumbnail.html" . .RelPermalink }}とすることで、同一記事がトップ・一覧・詳細などの複数箇所に登場する場合の重複計算を完全に排除しました。
2. 正規表現(findRE)のコスト削減
本文中から画像タグや特定のIDを抽出する「正規表現」は非常に強力ですが、全ページで無条件に走らせるとCPUに多大な負荷をかけます。
- 文字列検索による「ガード節」の追加
findREを実行する前に、まずstrings.Containsで対象の断片が存在するかをチェック。- 「画像が含まれていないページ」では重い正規表現処理を即座にスキップさせることで、処理の空振りを防ぎました。
- 計算量の最適化
- 単純な比較演算を先行させることで、サイト全体の総演算量を大幅に削減。これがビルド時間短縮の決定打となりました。
3. デプロイ効率の向上
テンプレートの改善は、最終的なHTMLの構造そのものをスリムにします。これはビルド時間だけでなく、その後の転送フェーズにも恩恵をもたらします。
- 転送データのスリム化
- テンプレート内の無駄なループや冗長な記述を整理したことで、ファイル1つあたりのデータ量が微減。
- これが全ファイル分積み重なることで、ネットワーク転送量とサーバー側のディスク書き込み負荷を軽減させました。
- rsyncとの親和性
- ファイルサイズの変化のみを検知する同期設定(
--size-only)と組み合わせることで、テンプレート修正がない時の差分検知がスムーズになり、安定したデプロイ環境を実現しました。
- ファイルサイズの変化のみを検知する同期設定(
まとめ
今回の改善により、これまで約18分かかっていたビルドから公開完了までの待ち時間を、**約12分(3分の2)**まで圧縮することに成功しました。
大規模サイトの運用においては、「いかに計算をサボるか(キャッシュするか)」、そして**「いかに重い処理を回避するか」**という視点が、サーバーのスペック以上に重要であることを再確認しました。
静的サイトの肥大化に悩む方の参考になれば幸いです。
