SPAのクライアントサイドルーティングをCloudFront Functionsで最適化する

SPAのクライアントサイドルーティングをCloudFront Functionsで最適化する

Author image

facebook logohatena logotwitter logo
Clock Icon2025.04.29

はじめに

SPAをAWS上でホスティングする場合、クライアントサイドルーティングに関する問題が発生することがあります。本記事では、CloudFront Functionsを使用してこの問題を効率的に解決する方法を紹介します。

CloudFront Functionsは、エッジロケーションで実行される軽量なJavaScript関数で、以下の特徴があります。

  • 平均1ms未満の超低レイテンシー実行
  • グローバルに分散されたエッジロケーションでの処理
  • サーバーレスで自動スケーリング
  • 単純な処理に最適化された軽量設計

https://dev.classmethod.jp/articles/amazon-cloudfront-functions-release/

SPAのルーティング問題の概要

SPAをCloudFrontとS3で配信する際に発生する主な問題は、次のようなケースでの404エラーです。

  • /products/123のようなサブパスに直接アクセスした場合
  • SPAページのリロード時
  • ブックマークからアクセスした場合

これは、SPAのルーティングがクライアントサイドJavaScriptで処理される一方、S3にはその実際のパスに対応するファイルが存在しないためです。例えば、/products/123というリクエストがS3に届いた場合、そのパスのファイルは実際には存在しないため、エラーになります。

解決アプローチの比較

SPAのルーティング問題には主に2つの解決策があります。

1. CloudFront Functionsによる解決(推奨)

特徴:

  • エッジでのリクエスト書き換えによる高速処理
  • 複数オリジン環境での選択的適用が可能
  • レイテンシーが低く、コスト効率が高い

2. カスタムエラーページによる解決

特徴:

  • 設定は比較的簡単
  • ただし、オリジンへのリクエスト→エラー→リダイレクトという多段処理が発生
  • 複数オリジン環境では問題が生じる可能性がある(APIからの正常なエラーコードも変換されるため)

パフォーマンスとコスト効率を重視する場合は、CloudFront Functionsによる解決が明らかに優れています。

CloudFront Functionsの実装例

以下は、SPAのルーティング問題を解決するための実用的な実装例です。この関数は、拡張子のないパスや特定のパターンに対して適切な処理を行います。

function handler(event) {
    var request = event.request;
    var uri = request.uri;

    // 静的アセット(拡張子を持つファイル)はそのまま処理
    if (uri.match(/\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|json|xml)$/)) {
        return request;
    }
    
    // APIパスなど特定のパスを除外(必要に応じてカスタマイズ)
    // 同じディストリビューションでAPIも配信している場合など
    if (uri.startsWith('/api/')) {
        return request;
    }
    
    // 以下の条件でindex.htmlにリダイレクト:
    // 1. ファイル拡張子がない場合(/about, /products/123など)
    // 2. パスがスラッシュで終わる場合(/about/, /products/など)
    if (!uri.includes('.') || uri.endsWith('/')) {
        // パターン1: URIがスラッシュで終わる場合
        if (uri.endsWith('/')) {
            request.uri += 'index.html';
        } 
        // パターン2: 拡張子を持たないパス
        else if (!uri.includes('.')) {
            request.uri += '/index.html';
        }
    }
    
    return request;
}

制限事項と注意点

CloudFront Functionsには以下の制限があります。

  • 関数の持続時間:サブミリ秒(1ms未満)
  • メモリ:2MB
  • 関数サイズ:最大10KB
  • JavaScript ES 5.1準拠(一部ES6機能はサポート)
  • 外部リソースへのアクセス不可

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/edge-functions-choosing.html

まとめ

CloudFront Functionsを使用したSPAルーティングの解決方法は、以下の理由でカスタムエラーページ方式より優れています。

  • 超低レイテンシー処理によるパフォーマンス向上
  • オリジンへのリクエスト削減によるコスト最適化
  • 複数オリジン環境での選択的適用による柔軟性
  • シンプルでわかりやすい実装

特に複合的なアーキテクチャ(フロントエンドとAPIを同じディストリビューションで提供する場合)では、CloudFront Functionsの使用が推奨されます。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.