パフォーマンス向けのヒューゴキャッシュ戦略

ハーグоサイトの開発と運用を最適化する

目次

Hugoのキャッシュ戦略は、静的サイトジェネレータのパフォーマンスを最大化するために不可欠です。Hugoは本来静的なファイルを生成するため、処理が高速ですが、複数のレイヤーで適切なキャッシュを実装することで、ビルド時間の大幅な改善、サーバー負荷の軽減、ユーザー体験の向上が可能です。

人気のあるテーマを使用している場合でも、Hugoで最も人気のあるテーマガイドに記載されているテーマや、カスタムテーマを使用している場合でも、これらのキャッシュ戦略はサイトのパフォーマンスを最適化するために役立ちます。

この包括的なガイドでは、ビルド時のキャッシュ、インクリメンタルビルド、CDN最適化、HTTPヘッダ、アセットキャッシュ戦略をカバーし、Hugoベースのウェブサイトの最適なパフォーマンスを実現するための方法を紹介します。

白い服を着たシェフとキャッシュ戦略 この素晴らしい画像は、AIモデルFlux 1 devによって生成されました。

Hugoのビルドキャッシュの理解

Hugoは内部のビルドキャッシュを維持し、処理済みコンテンツやアセットを保存して、次のビルドを高速化します。このキャッシュはresources/_genディレクトリに配置されており、以下を含みます:

  • レンダリングされたテンプレート:事前に処理されたテンプレートの出力
  • 処理済み画像:リサイズ、最適化、変換された画像
  • コンパイル済みアセット:圧縮されたCSSとJavaScript
  • リソースメタデータ:ファイルハッシュと処理結果

ビルドキャッシュの動作方法

hugoコマンドを実行すると、ジェネレータは以下の手順を実行します:

  1. キャッシュに既存の処理済みリソースを確認
  2. ファイルの変更日時とコンテンツハッシュを比較
  3. 変更されていないファイルの処理をスキップ
  4. 変更または新規のコンテンツのみを再構築

つまり、1000の投稿を持つサイトで1つの投稿を編集した場合、Hugoはその1つの投稿のみを処理し、影響を受けるページを再生成するだけで、サイト全体を再構築する必要はありません。

ビルドキャッシュの管理

Hugoのキャッシュの動作は、さまざまなコマンドラインフラグを使用して制御できます。Hugoのコマンドの包括的なリファレンスについては、Hugo Cheat Sheetをご覧ください:

# キャッシュをクリアしてすべてを再構築
hugo --ignoreCache

# カスタムキャッシュディレクトリを使用
export HUGO_CACHEDIR=/path/to/cache
hugo

# ファストレンダリングモードを無効化(フルリビルドを強制)
hugo server --disableFastRender

CI/CDパイプラインでは、ビルド間でキャッシュディレクトリを保持することで、デプロイを高速化できます。Gitea Actionsを使用してデプロイしている場合、Gitea ActionsでHugoウェブサイトをAWS S3にデプロイに関するガイドをご覧ください:

# GitHub Actionsワークフローの例
- name: Cache Hugo resources
  uses: actions/cache@v3
  with:
    path: resources/_gen
    key: ${{ runner.os }}-hugo-${{ hashFiles('**/content/**') }}

ファイルキャッシュの設定

Hugoは[caches]設定セクションを通じて、さまざまなキャッシュタイプの細かな制御を提供します。Hugoドキュメントによると、複数のキャッシュタイプを設定できます:

[caches]
  [caches.assets]
    dir = ':resourceDir/_gen'
    maxAge = -1
  [caches.getcsv]
    dir = ':cacheDir/:project'
    maxAge = -1
  [caches.getjson]
    dir = ':cacheDir/:project'
    maxAge = -1
  [caches.getresource]
    dir = ':cacheDir/:project'
    maxAge = -1
  [caches.images]
    dir = ':resourceDir/_gen'
    maxAge = -1
  [caches.misc]
    dir = ':cacheDir/:project'
    maxAge = -1
  [caches.modules]
    dir = ':cacheDir/modules'
    maxAge = -1

キャッシュタイプの説明

  • assets:Hugo Pipesから処理されたCSS、JavaScript、その他のアセットをキャッシュ
  • getcsvgetCSV関数で読み込まれたパース済みCSVファイルをキャッシュ
  • getjsongetJSON関数で読み込まれたパース済みJSONファイルをキャッシュ
  • getresourcegetResource関数でフェッチされたリモートリソースをキャッシュ
  • images:リサイズ、最適化、変換された処理済み画像をキャッシュ
  • misc:ミスセルaneousな操作のための汎用キャッシュ
  • modules:Hugoモジュールとその依存関係をキャッシュ

設定オプション

各キャッシュタイプは2つの設定オプションをサポートします:

  • dir:キャッシュされたファイルが保存される絶対ファイルシステムパス。使用可能なトークン:

    • :cacheDir - 設定されたキャッシュディレクトリに置き換えられます
    • :resourceDir - リソースディレクトリ(通常resources/_gen)に置き換えられます
    • :project - 現在のHugoプロジェクトのベースディレクトリ名に置き換えられます
  • maxAge:キャッシュエントリが有効な期間(期限切れになる前の時間):

    • 0 - キャッシュを無効化
    • -1 - キャッシュエントリが期限切れにならない(デフォルト)
    • 正の数 - 指定された期間後にキャッシュが期限切れ(例:3600で1時間)

カスタムキャッシュ設定の例

特定のユースケースに合わせてキャッシュ設定をカスタマイズできます:

[caches]
  # 処理済み画像を永久にキャッシュ
  [caches.images]
    dir = ':resourceDir/_gen/images'
    maxAge = -1
  
  # JSON APIの応答を1時間キャッシュ
  [caches.getjson]
    dir = ':cacheDir/:project/json'
    maxAge = 3600
  
  # リモートリソースを24時間キャッシュ
  [caches.getresource]
    dir = ':cacheDir/:project/resources'
    maxAge = 86400

この設定により、以下のことが可能です:

  • 処理済み画像を永久にキャッシュ(それらは決定論的であるため)
  • 動的なコンテンツのためにJSONデータを1時間ごとに更新
  • リモートリソースを24時間キャッシュ(新鮮さとパフォーマンスのバランス)

:projectトークンにより、各Hugoプロジェクトが孤立したキャッシュを持つため、hugo --gc(ガベージコレクション)を実行しても、現在のプロジェクトのキャッシュのみに影響を与えます。

インクリメンタルビルド

Hugoのインクリメンタルビルドシステムは、その最も強力な機能の一つです。ファイルレベルで変更を追跡し、必要なものだけを再構築します。

インクリメンタルビルドの有効化

インクリメンタルビルドはデフォルトで有効です。Hugoは自動的に:

  • ファイルの依存関係を追跡
  • 変更されたページとその依存関係のみを再構築
  • 更新のための依存関係グラフを維持

ビルドパフォーマンスのヒント

  1. 開発にはhugo serverを使用:開発サーバーはインクリメンタルビルドを自動的に使用
  2. --minifyは本番環境でのみ使用:圧縮はオーバーヘッドを追加するため、最終ビルドのみに使用
  3. 画像処理を最適化:Hugoの画像処理機能を効率的に使用:
[imaging]
  bgColor = '#ffffff'
  hint = 'photo'
  quality = 75
  resampleFilter = 'box'
  1. リソース処理を制限:実際に使用されている画像やアセットのみを処理

CDNキャッシュ戦略

コンテンツ配信ネットワーク(CDN)はグローバルなパフォーマンスにおいて重要です。HugoサイトをCloudFront、Cloudflare、NetlifyなどのCDNにデプロイする際には、適切にキャッシュを設定してください。AWS S3にHugoサイトをデプロイし、CloudFrontを使用する詳細な手順については、Hugo生成されたウェブサイトをAWS S3にデプロイに関するガイドをご覧ください。

CloudFrontの設定

AWS CloudFrontでのデプロイの場合、キャッシュの動作を設定します:

# config.toml
[[deployment.targets]]
name = "production"
URL = "s3://your-bucket?region=us-east-1"
cloudFrontDistributionID = "E1XIDGUJGD9BU9"

CloudFrontのキャッシュの動作を設定します:

  • 静的アセット.css.js.jpg.pngなど):

    • TTL:1年(31536000秒)
    • キャッシュポリシー:CachingOptimized
    • 圧縮:はい
  • HTMLページ.html):

    • TTL:1時間(3600秒)
    • キャッシュポリシー:CachingDisabled(オリジンヘッダ付き)
    • 圧縮:はい

キャッシュの無効化

デプロイ時にキャッシュの無効化を自動化します:

# デプロイ後にCloudFrontキャッシュを無効化
aws cloudfront create-invalidation \
  --distribution-id E1XIDGUJGD9BU9 \
  --paths "/*"

またはHugoのデプロイ機能を使用します:

[[deployment.targets]]
name = "production"
URL = "s3://your-bucket"
cloudFrontDistributionID = "E1XIDGUJGD9BU9"

Hugoはデプロイ時に自動的にキャッシュを無効化します。

アセット最適化とキャッシュ

Hugoはキャッシュと統合されたアセット処理を提供しています。

リソースハッシュ

Hugoはファイル名にコンテンツハッシュを自動的に追加できます:

{{ $css := resources.Get "css/main.css" | minify | fingerprint }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}">

これにより、main.min.abc123def456.cssなどのファイル名が生成され、コンテンツが変更されるとハッシュが変更されるため、長期的なキャッシュが可能になります。

画像処理とキャッシュ

Hugoの組み込み画像処理を使用して画像を効率的に処理します。Hugoは処理済み画像をキャッシュするため、同じ画像を複数回リサイズしても一度だけ処理されます。OpenGraph画像メタデータの生成など、より高度な画像処理については、Hugo静的サイトジェネレータでのOpenGraph画像メタデータに関するガイドをご覧ください:

{{ $image := resources.Get "images/photo.jpg" }}
{{ $resized := $image.Resize "800x600" }}
<img src="{{ $resized.RelPermalink }}" alt="Photo">

アセットバンドリング

アセットをバンドルして圧縮します:

{{ $css := slice 
    (resources.Get "css/reset.css")
    (resources.Get "css/main.css")
    (resources.Get "css/components.css")
  | resources.Concat "css/bundle.css"
  | minify
  | fingerprint
}}
<link rel="stylesheet" href="{{ $css.RelPermalink }}">

これにより、単一のキャッシュされ、圧縮され、フィンガープリントされたCSSファイルが作成されます。

サービスワーカーのキャッシュ(オプション)

高度なキャッシュ戦略を実装するには、サービスワーカーの使用を検討してください:

基本的なサービスワーカー

// sw.js
const CACHE_NAME = 'hugo-site-v1';
const urlsToCache = [
  '/',
  '/css/main.css',
  '/js/main.js',
  '/images/logo.png'
];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then((cache) => cache.addAll(urlsToCache))
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => response || fetch(event.request))
  );
});

サービスワーカーの登録

<!-- Hugoテンプレート内で -->
<script>
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js');
}
</script>

モニタリングと最適化

ビルド時間のモニタリング

ビルドパフォーマンスを追跡します:

# ビルド時間を計測
time hugo

# 詳細な出力を使用して処理中の内容を確認
hugo --verbose

キャッシュヒット率

CDNのアナリティクスダッシュボードを通じてCDNキャッシュヒット率をモニタリングしてください。目標は:

  • 静的アセット:95%以上のキャッシュヒット率
  • HTMLページ:60%〜80%のキャッシュヒット率(更新頻度に応じて)

パフォーマンステスト

以下のツールを使用してください:

  • Lighthouse:キャッシュの有効性をテスト
  • WebPageTest:キャッシュヘッダを分析
  • GTmetrix:パフォーマンスメトリクスをモニタリング

ベストプラクティスの要約

  1. Hugoのビルドキャッシュを有効化:処理済みリソースをHugoがキャッシュ
  2. インクリメンタルビルドを使用:変更されたものだけを再構築
  3. CDNを適切に設定:アセットは長時間、HTMLは短時間
  4. 適切なHTTPヘッダを設定:ハッシュされたアセットにはimmutableを使用
  5. アセットにフィンガープリントを設定:ファイル名にコンテンツハッシュを追加
  6. デプロイ時にキャッシュを無効化:ユーザーが更新を確認できるように
  7. パフォーマンスをモニタリング:ビルド時間とキャッシュヒット率を追跡
  8. 画像を最適化:Hugoの画像処理を効率的に使用
  9. アセットをバンドル:HTTPリクエストを減らすためにCSS/JSをバンドル
  10. サービスワーカーを検討:オフラインファーストや高度なキャッシュのニーズに

結論

Hugoサイトの効果的なキャッシュ戦略は、複数のレイヤーを含みます:ビルド時のキャッシュで開発を高速化、CDNキャッシュでグローバルなパフォーマンスを向上、適切なHTTPヘッダでブラウザキャッシュを実現します。これらの戦略を実装することで、以下が達成できます:

  • 高速なビルド:インクリメンタルビルドとビルドキャッシュでビルド時間を短縮
  • より良いパフォーマンス:CDNとブラウザキャッシュでロード時間を改善
  • サーバー負荷の軽減:エッジで静的アセットをキャッシュ
  • 改善されたユーザー体験:高速なページロードとオフライン機能

キャッシュはパフォーマンスと新鮮さのバランスを取る必要があります。静的アセットは積極的にキャッシュできますが、HTMLは更新が迅速に見えるように短いキャッシュ時間に設定する必要があります。

有用なリンク