【事例満載】Accept-CH ヘッダーで Web サイトを高速化・軽量化する方法


仕組み

  1. サーバーが Accept-CH ヘッダーを送信
    ウェブサーバーは、クライアントがどのクライアントヒントをサポートしているか、そしてそれらをどのくらいの期間保持できるかを伝えるために、Accept-CH ヘッダーをレスポンスに含めます。
  2. ブラウザがクライアントヒントを送信
    ブラウザは、Sec-CH-* ヘッダーと呼ばれる一連のヘッダーを使用して、サポートしているクライアントヒントをサーバーに送信します。これらのヘッダーには、ブラウザのユーザーエージェント、画面解像度、色空間、エンコーディングサポートなどに関する情報が含まれます。
  3. サーバーが応答を最適化
    サーバーは、受信したクライアントヒントに基づいて、応答を最適化することができます。例えば、ブラウザが Brotli エンコーディングをサポートしていることがわかれば、サーバーは Brotli で圧縮されたコンテンツを送信することができます。

利点

  • セキュリティの向上
    クライアントヒントの一部は、ブラウザの指紋情報に使用される可能性があります。しかし、Accept-CH ヘッダーと Sec-CH-UA-Mitigation ヘッダーを併用することで、このリスクを軽減することができます。
  • 帯域幅の節約
    クライアントがサポートしていないコンテンツを無駄に送信する必要がなくなるため、帯域幅を節約できます。
  • ページの読み込み速度の向上
    クライアントヒントにより、サーバーはブラウザの機能をより良く理解できるようになり、より効率的なコンテンツ配信が可能になります。

以下の例は、Accept-CH ヘッダーと Sec-CH-* ヘッダーの使用例を示しています。

サーバー側の応答

HTTP/2 200 OK
Content-Type: text/html
Accept-CH: Sec-CH-UA, Sec-CH-UA-Platform, Sec-CH-Width
GET /index.html HTTP/2
Sec-CH-UA: @Chromium;v=105;OS=Windows;WOW64
Sec-CH-UA-Platform: Windows;WOW64
Sec-CH-Width: 1920
  • クライアントヒントは、プライバシー上の懸念事項があるため、注意して使用する必要があります。
  • Accept-CH ヘッダーは、まだ比較的新しい機能であり、すべてのブラウザでサポートされているわけではありません。



このコードは例示のみを目的としており、本番環境で使用されるように設計されていません。実際の使用前に、要件に合わせてコードを調整する必要があります。

サーバー側のコード (Python)

from http.server import HTTPServer, BaseHTTPRequestHandler

class MyRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        # Accept-CH ヘッダーを設定
        self.send_header('Accept-CH', 'Sec-CH-UA, Sec-CH-UA-Platform, Sec-CH-Width')

        # コンテンツを送信
        self.send_header('Content-Type', 'text/html')
        self.end_headers()
        self.wfile.write(b'<html><body><h1>Accept-CH Example</h1></body></html>')

with HTTPServer(('localhost', 8000), MyRequestHandler) as server:
    print('Starting server on port 8000...')
    server.serve_forever()

クライアント側のコード (JavaScript)

fetch('http://localhost:8000')
  .then(response => response.headers.get('Sec-CH-UA'))
  .then(userAgent => console.log('User Agent:', userAgent));

このコードの説明

サーバー側

  • do_GET メソッドは、単純な HTML ページを送信します。
  • do_GET メソッドは、Accept-CH ヘッダーを "Sec-CH-UA, Sec-CH-UA-Platform, Sec-CH-Width" に設定します。
  • MyRequestHandler クラスは、do_GET メソッドをオーバーライドして、GET リクエストを処理します。
  • HTTPServer クラスを使用して、ポート 8000 で HTTP サーバーを作成します。
  • コンソールにユーザーエージェントを出力します。
  • response.headers.get('Sec-CH-UA') を使用して、Sec-CH-UA ヘッダーの値を取得します。
  • fetch() APIを使用して、http://localhost:8000 に GET リクエストを送信します。


しかし、以下の方法で、Accept-CH が提供していた機能の一部を代替することができます。

User Agent String (UAS)

従来の手段として、User Agent String (UAS) を使用する方法があります。UASは、ブラウザやオペレーティングシステムなどの情報を識別するために使用されるヘッダーです。

利点:

  • シンプルで実装が容易です。
  • 多くの Web サイトやサーバーで既に広く使用されているため、互換性が高いです。

欠点:

  • 詳細な情報が得られない場合があります。UAS は、ブラウザや OS のバージョンなど、限られた情報しか提供しません。
  • プライバシー上の問題があります。UAS には、ユーザーの個人情報が含まれる可能性があるため、悪用されるリスクがあります。

User Agent Client Hints (UA-CH)

UA-CH は、Accept-CH の後継として提案されている新しいヘッダーです。UA-CH は、UAS よりも詳細な情報を提供し、プライバシー保護も強化されています。

  • プライバシー保護が強化されています。ユーザーエージェントの一部のみを選択的に送信することができます。
  • UAS よりも詳細な情報 (ブラウザのバージョン、画面解像度、色空間など) を提供できます。
  • Accept-CH と互換性がありません。
  • まだ新しい技術であり、すべてのブラウザでサポートされているわけではありません。

上記以外にも、以下のような方法で Accept-CH の一部機能を代替することができます。

  • Server-side device detection
    サーバー側でデバイスを検出するために、さまざまな手法 (例: ブラウザフィンガープリント) を使用します。
  • Feature detection
    クライアントが特定の機能をサポートしているかどうかを JavaScript で検出します。

どの代替手段が最適かは、要件によって異なります。 プライバシーを重視する場合は UA-CH が、互換性を重視する場合は UAS が適している可能性があります。