カテゴリ: Flask 更新日: 2026/03/15

FlaskでHTTPヘッダーを自在に操る!Cache-ControlとETagで実現する高速化

FlaskでHTTPヘッダー(Cache-Control, ETag)を設定する方法まとめ
FlaskでHTTPヘッダー(Cache-Control, ETag)を設定する方法まとめ

先生と生徒の会話形式で理解しよう

生徒

「Flaskで作ったサイトの表示を速くしたいのですが、サーバーの負荷を減らす良い方法はありますか?」

先生

「それなら、HTTPヘッダーを使ってブラウザにキャッシュを指示するのが効果的ですよ。特にCache-ControlやETagという仕組みが重要です。」

生徒

「エイチティーティーピーヘッダー?難しそうな言葉ですね。初心者の私でも設定できるんでしょうか?」

先生

「大丈夫ですよ。ブラウザとサーバーの間で交わされるお手紙の追伸のようなものです。具体的な書き方を見ていきましょう!」

1. HTTPヘッダーとキャッシュの役割を知ろう

1. HTTPヘッダーとキャッシュの役割を知ろう
1. HTTPヘッダーとキャッシュの役割を知ろう

Webサイトを表示するとき、あなたのパソコン(ブラウザ)はサーバーに対して「このページを見せてください」というリクエストを送ります。サーバーはそれに応えて、ページのデータと一緒に「HTTPヘッダー」という付加情報を返します。これは、データの取り扱い説明書のようなものです。

この説明書の中に「このデータはしばらく保存して使い回していいよ」と書いてあれば、ブラウザは次に同じページを開くときに、わざわざサーバーにデータを取りに行かなくなります。これが「キャッシュ」です。キャッシュを正しく設定すると、インターネットの通信量が減り、サイトの表示速度が劇的にアップします。パフォーマンス最適化の基本中の基本と言えるテクニックです。

2. Cache-Controlで保存期間を指示する方法

2. Cache-Controlで保存期間を指示する方法
2. Cache-Controlで保存期間を指示する方法

Cache-Control(キャッシュコントロール)は、ブラウザに「いつまでデータを保存しておくべきか」を具体的に伝えるためのヘッダーです。例えば、1時間保存させたい場合は max-age=3600 という数値を指定します。これは秒単位で指定する決まりになっています。

Flaskでは、返信(レスポンス)を返す際にこのヘッダーを付け加えることができます。プログラミングが初めての方でも、決まった形を覚えるだけで簡単に実装できます。サーバー側の負担を減らすための第一歩として、非常に汎用性が高い設定です。


from flask import Flask, make_response

app = Flask(__name__)

@app.route("/cache-demo")
def cache_demo():
    # 画面に表示する内容を作成
    resp = make_response("このページは10分間キャッシュされます。")
    
    # Cache-Controlヘッダーを設定(600秒 = 10分)
    # publicは、誰でもキャッシュして良いという意味です
    resp.headers["Cache-Control"] = "public, max-age=600"
    
    return resp

3. ETagでデータの変更を確認する仕組み

3. ETagでデータの変更を確認する仕組み
3. ETagでデータの変更を確認する仕組み

ETag(イータグ)は、データの「指紋」のようなものです。サーバーはデータの内容を元に短い英数字のラベルを作り、ブラウザに渡します。次にブラウザがアクセスしてきたとき、ブラウザは「手元にある指紋はこれだけど、中身は変わった?」とサーバーに聞きに行きます。

もし中身が変わっていなければ、サーバーは「変わってないよ(304 Not Modified)」という短い返事だけを返します。重いデータを送る必要がなくなるため、体感速度が向上します。Cache-Controlが「期限」を決めるのに対し、ETagは「中身が同じか」を確認するための道具だと覚えておきましょう。

4. FlaskでETagを手動で設定してみよう

4. FlaskでETagを手動で設定してみよう
4. FlaskでETagを手動で設定してみよう

Flaskを使って、自分でETagを計算して設定する方法を見てみましょう。データの更新頻度が低いページなどでこれを使うと、無駄なデータ転送をカットできます。ここでは、簡単な文字列を指紋として使ってみます。


from flask import Flask, make_response, request

app = Flask(__name__)

@app.route("/etag-demo")
def etag_demo():
    content = "最新のニュース記事の内容です。"
    # 本来は内容から計算しますが、ここでは固定の指紋を作成
    tag = "news-v1"
    
    # ブラウザが持っている指紋を確認
    if request.headers.get("If-None-Match") == tag:
        # 指紋が一致したら「変更なし」を返す
        return "", 304

    # 一致しない場合は新しいデータと指紋を返す
    resp = make_response(content)
    resp.set_etag(tag)
    return resp

5. 条件付きリクエストと304エラーのメリット

5. 条件付きリクエストと304エラーのメリット
5. 条件付きリクエストと304エラーのメリット

先ほどのコードに出てきた「304」という数字は、エラーではなく「変更がないので、手元のキャッシュを使ってね」という合図です。パソコン初心者の方は、数字が出てくると不安になるかもしれませんが、これは非常にポジティブな信号です。

通常、画像や文章を送るには時間がかかりますが、304の合図はほんの数文字のデータで済みます。これにより、スマートフォンの通信制限を気にしているユーザーにも優しい、軽量なWebサイトが実現できます。Googleの検索エンジンも、こうした効率的なサイトを好む傾向にあります。SEO対策としても、適切なステータスコードを返すことは非常に重要です。

6. after_requestで全ページにキャッシュ設定を適用

6. after_requestで全ページにキャッシュ設定を適用
6. after_requestで全ページにキャッシュ設定を適用

ページが増えてくると、一つひとつの関数にヘッダーを書くのは大変です。Flaskには after_request という便利な仕組みがあり、これを使うとすべてのページの返信に対して一括で処理を加えることができます。共通のルールを一箇所にまとめることで、ミスも減りますし、管理も楽になります。


@app.after_request
def add_header(response):
    # すべてのレスポンスにキャッシュ設定を追加する
    # no-cacheは、毎回サーバーに確認してねという意味です
    if "Cache-Control" not in response.headers:
        response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
        response.headers["Pragma"] = "no-cache"
    return response

この例では、逆に「キャッシュをさせない」ための設定をしています。銀行の残高画面など、常に最新でないと困るページにはこのような厳格な設定が必要です。高速化したい場所と、鮮度が大事な場所で設定を使い分けるのがプロの技です。

7. ブラウザの「検証モード」でヘッダーを確認する

7. ブラウザの「検証モード」でヘッダーを確認する
7. ブラウザの「検証モード」でヘッダーを確認する

設定したヘッダーが正しく動いているか確認するには、ブラウザの隠し機能を使います。Google Chromeなどのブラウザで、キーボードの一番上にある F12 というキーを押してみてください。右側に「デベロッパーツール」という画面が出てきます。

そこの「Network(ネットワーク)」というタブを開いてからサイトを読み込み、ファイル名をクリックすると「Headers(ヘッダー)」という項目が見えます。ここに自分が書いた Cache-ControlETag が表示されていれば、設定は成功です!自分で書いたコードが、インターネット上の見えない信号として動いているのを確認するのは、とてもワクワクする瞬間ですよ。

8. 静的ファイルと動的ファイルの使い分け

8. 静的ファイルと動的ファイルの使い分け
8. 静的ファイルと動的ファイルの使い分け

Flaskで扱うファイルには、画像やデザインなどの「静的ファイル」と、プログラムがその場で作る「動的ファイル」があります。画像などは一度設定すれば長く保存して問題ありませんが、ユーザーの名前が表示されるような動的なページは、キャッシュの扱いを慎重にする必要があります。

誰が見ても同じ画像には max-age を長く設定し、人によって変わるページには ETag を使って変更を確認する、というように使い分けるのが理想的です。この戦略を立てるだけでも、サイトのパフォーマンスは大幅に改善されます。初心者のうちは、まずは画像などの静的ファイルからキャッシュに慣れていくのがおすすめです。

9. Flaskの拡張機能を使った自動化

9. Flaskの拡張機能を使った自動化
9. Flaskの拡張機能を使った自動化

手動でヘッダーを設定するのに慣れてきたら、世の中にある便利な「拡張機能」を使ってみるのも良いでしょう。例えば Flask-Caching という道具を使えば、もっと短いコードで高度なキャッシュ管理ができるようになります。しかし、その裏側で今回学んだ Cache-ControlETag が動いていることを知っているかどうかが、プログラミングの上達を左右します。

基本を理解していれば、もしトラブルが起きてサイトが表示されなくなっても、どこを直せばいいか見当がつくようになります。一見地味な設定ですが、Webの仕組みを支えるとても大切な基礎知識なのです。一歩ずつ、着実にレベルアップしていきましょう。

10. パフォーマンス最適化への第一歩を踏み出そう

10. パフォーマンス最適化への第一歩を踏み出そう
10. パフォーマンス最適化への第一歩を踏み出そう

ここまで読んでくださったあなたは、もう立派なWebアプリ開発者の仲間入りです。HTTPヘッダーを操作してブラウザに指示を出すという行為は、サイトの表示を速くするだけでなく、サーバー資源の節約や環境負荷の低減にも繋がります。


# 最後に:一番よく使う「1日保存」の便利な設定
@app.route("/static-content")
def static_content():
    response = make_response("これは1日中キャッシュされるコンテンツです。")
    # 86400秒 = 24時間
    response.cache_control.max_age = 86400
    return response

まずは自分の作った小さなアプリに、数秒のキャッシュを設定するところから始めてみてください。画面がパッと切り替わる快適さを知ると、プログラミングがもっともっと楽しくなりますよ。快適なWebサイト作りを目指して、今日学んだことをぜひ活用してくださいね!

カテゴリの一覧へ
新着記事
New1
Python
Pythonの関数を引数に渡す方法を初心者向けにやさしく解説!高階関数の使い方も完全ガイド
New2
Python
Pythonのクロージャー(Closure)とは?関数内関数とnonlocalの活用
New3
Python
Pythonのスコープとは?ローカル変数・グローバル変数の違いと使い分け
New4
Python
Pythonのreturn文の使い方!値を返す関数の書き方と注意点
人気記事
No.1
Java&Spring記事人気No1
Python
Pythonの文字列を1文字ずつ処理する方法!for文やlist化の活用例
No.2
Java&Spring記事人気No2
Python
Pythonでトランザクション処理を実装する方法を完全解説!commit・rollbackで安全なSQL操作
No.3
Java&Spring記事人気No3
Flask
Flaskとは何か?初心者向けにできること・特徴・インストール手順までやさしく解説
No.4
Java&Spring記事人気No4
Flask
FlaskでAPIのレスポンスをキャッシュ!通信負荷を軽減して爆速にする方法
No.5
Java&Spring記事人気No5
Flask
Flaskでデータベースエラーを処理する方法!初心者にもわかる例外の使い方
No.6
Java&Spring記事人気No6
Flask
FlaskのSQLAlchemyでフィルタリング検索!filter, filter_byの使い方完全ガイド
No.7
Java&Spring記事人気No7
Python
Pythonの文字列から一部を抽出する方法!スライスを使った基本的な切り出し方
No.8
Java&Spring記事人気No8
Flask
Flaskで開発中にデータベースを初期化する方法!初心者でもわかる便利なTips