ISRと天気予報サイトでの使用

外部API利用制限を考慮した天気予報サイトでの実践的な活用

2026年1月

1. はじめに

このドキュメントでは、Next.jsのレンダリング方式の一つであるISR(Incremental Static Regeneration)について解説します。 その後、外部APIの利用回数制限がある場合に、どのようにISRが有効かを天気予報サイトを例に説明します。

本プロジェクトの概要

サイネージ向けのお天気サイトです。全国、地区(北海道〜九州)、都道府県、市町村と階層的に天気情報を表示します。 天気データはOpenWeatherMap APIから取得しています。

2. Webページのレンダリング方式

まず、Webページがどのタイミングで生成されるかによって、大きく4つの方式があります。

SSG Static Site Generation

ビルド時にHTMLを生成

  • 最速の表示
  • 更新にはビルドが必要
  • 企業サイト等に最適

SSR Server-Side Rendering

リクエスト毎にHTMLを生成

  • 常に最新データ
  • サーバー負荷が高い
  • 外部API呼び出し多

CSR Client-Side Rendering

ブラウザでHTMLを生成

  • 初期表示が遅い
  • SEOに課題あり
  • 管理画面等に最適

レンダリング方式の比較表

方式 生成タイミング/場所 表示速度 データ鮮度 API呼び出し
SSG ビルド時 最速 ビルド時点 ビルド時のみ
SSR リクエスト毎 遅め 常に最新 リクエスト毎
ISR 定期的に再生成 高速 設定間隔で更新 再検証時のみ
CSR ブラウザ上 初期は遅い 常に最新 リクエスト毎

3. ISRの仕組み

ISRは「静的サイトのパフォーマンス」と「動的サイトのデータ鮮度」を両立する仕組みです。

ISRの動作フロー

ユーザーがアクセス
→
キャッシュされた
HTMLを即座に返却
→
バックグラウンドで
データ再取得
→
次回アクセス時に
更新されたHTML

ポイント:stale-while-revalidate パターン

ユーザーにはまず「古いかもしれないが有効なデータ(stale)」を即座に返し、 裏側で「新しいデータを取得(revalidate)」します。 これにより、ユーザーは待たずに高速表示を体験できます。

4. 本プロジェクトでの活用

4.1 なぜISRを採用したか

本プロジェクトでは、OpenWeatherMap APIを使用して天気データを取得しています。このAPIには以下の制限があります。

OpenWeatherMap API の利用制限
プラン 制限 リクエスト数
無料プラン レートリミット 60リクエスト/分
One Call API 3.0 日次リミット 1,000リクエスト/日(無料枠)

もしSSR(リクエスト毎に取得)を採用していた場合、ユーザーがアクセスするたびにAPIを呼び出すため、すぐに制限に達してしまいます。

4.2 レンダリング方式の選択理由

方式 天気サイトでの問題 採用可否
SSG 天気データが更新されない(ビルド時点のまま) 不適
SSR API制限にすぐ達する 不適
CSR API制限にすぐ達する 不適
ISR 定期更新でAPI呼び出しを最小化しつつ鮮度を保つ 最適

5. 実装箇所(コード抜粋)

5.1 OpenWeatherMap APIでの実装

Next.jsでは、fetch関数にnext.revalidateオプションを指定することでISRを実現します。

lib/api-client.ts

/**
 * OpenWeatherMap API への共通リクエスト処理
 */
async function fetchFromOpenWeatherMap<T>(
  endpoint: string,
  params: Record<string, string | number>
): Promise<T> {
  const url = new URL(`${OPENWEATHERMAP_BASE_URL}${endpoint}`)

  // パラメータ設定...

  const response = await fetch(url.toString(), {
    next: { revalidate: 1800 }, // 30分間キャッシュ、その後再検証
  })

  return response.json() as Promise<T>
}

revalidate: 1800 の意味

この設定により、取得したデータは30分間(1800秒)キャッシュされます。 30分経過後、次のリクエスト時にバックグラウンドでデータが再取得されます。

5.2 One Call API 3.0 でも同様に実装

lib/api-client.ts

/**
 * One Call API 3.0 への共通リクエスト処理
 * 現在の天気、48時間の時間別予報、8日間の日別予報を一度に取得
 */
async function fetchFromOneCallApi<T>(
  endpoint: string,
  params: Record<string, string | number>
): Promise<T> {
  const url = new URL(`${OPENWEATHERMAP_ONECALL_URL}${endpoint}`)

  // パラメータ設定...

  const response = await fetch(url.toString(), {
    next: { revalidate: 1800 }, // 30分間キャッシュ、その後再検証
  })

  return response.json() as Promise<T>
}

7. まとめ

ISR採用のメリット
  • API利用制限への対応:定期更新により呼び出し回数を削減
  • データの鮮度維持:30分間隔で自動更新
  • 上記に伴うコスト削減:API従量課金の抑制

ISRの適用場面に関する補足

ISRは、天気予報サイトのように「リアルタイム性は必要だが秒単位の更新は不要」なコンテンツに最適です。 ニュースサイト、商品情報ページ、ブログ記事なども同様にISRの恩恵を受けられます。