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の恩恵を受けられます。