PerfData

コードとヘッダ、Webページを動かす二つの歯車

Webパフォーマンス入門: HTTPヘッダ その2

2018年5月22日
著者: Kameerath Kareem
翻訳: 小川 純平

この記事は米Catchpoint Systems社のブログ記事 Web Performance 101: HTTP Headers Pt. 2の翻訳です。
Spelldataは、Catchpointの日本代理店です。
この記事は、Catchpoint Systemsの許可を得て、翻訳しています。


前回の記事では、基本的なHTTPヘッダについて、それらがどのように実装されているかについて、確認しました。
ヘッダはページのパフォーマンスに様々な形で影響しますが、デジタル体験に対して良くも悪くも影響する、3つの要素があります。

この記事では、Webサイトパフォーマンスの最適化にあたり、ヘッダがどのような効果があるかお話します。
ここでは、キャッシュ、圧縮、セキュリティの実装を効果的に助けるヘッダと、それが全体のデジタル体験にどのように影響するかについてフォーカスしていきます。

キャッシュヘッダ

キャッシュは、パフォーマンスに大きく影響する、重要なWebページ最適化のテクニックです。
リソースがキャッシュされるということは、リソースのコピーがキャッシュサーバやローカルサーバに保存されたということを意味します。
キャッシュによりネットワークのレイテンシが大きく軽減され、ページのレンダリングを高速化することができます。
現在使われているキャッシュのテクニックには、以下の3つがあります。

キャッシュ無し

No Cache設定がされている場合は、全ての同一リソースへのリクエストがサーバへと到達します。

キャッシュ無し

共有キャッシュ

キャッシュしたリソースは、共有されたネットワーク上にある場所に保存されます。
これらのリソースは、異なるユーザが、複数回再利用するもので、これによりサーバへのラウンドトリップの回数が少なくなり、ネットワークの混雑と待ち時間を低減させます。

共有キャッシュ

(※訳注)共有キャッシュは、そのネットワーク上の位置によって、名前が変わります。

フォワードキャッシュ
サーバ側でのキャッシュ機構。動的に生成されて再利用可能なページなどをキャッシュする。
CDN(Content Delivery Network)
インターネット上に展開したキャッシュサーバ群でのキャッシュ機構。Edge(エンドユーザに近い側)に配置されたサーバでキャッシュする事で、ネットワークの物理的距離による遅延を短縮し、且つ、Webサーバへのアクセスの集中を回避する。
リバースキャッシュ
Edgeに配置されたサーバでキャッシュする事で、ネットワーク帯域の使用量を軽減し、帯域不足による遅延を短縮する。キャリア、ISP、企業が、自社が所有しているネットワークに設置する。

ローカル(プライベート)キャッシュ

キャッシュはブラウザによって、ローカルマシンに保存されます。
ブラウザがページ上のコンテンツをキャッシュすることで、Webサーバに対して既にダウンロードしキャッシュしたリソースを、繰り返しリクエストを送信する必要がなくなり、ページの読み込み時間を大きく減らすことができます。

ローカル(プライベート)キャッシュ

キャッシュの振る舞いをコントロールするためのHTTPヘッダを見ていきましょう。

Cache-control

Cache-controlヘッダは、セッションに対するキャッシュのポリシーを定義します。
HTTPリクエスト・レスポンスに対して設定できるパラメータがいくつかあり、これらのパラメータは、クライアントとサーバがどのようにキャッシュを処理するかを示します。

  1. キャッシュを保存しないように指定する場合、次のオプションを使用します。
    
    Cache-Control: no-store
    Cache-Control: no-cache, no-store, must-revalidate
    
  2. キャッシュバリデーションをオリジンサーバで行うように指定する場合、次のオプションを使用します。
    Cache-Control: no-cache
  3. 使用するキャッシュのタイプ、すなわち、リソースがどこのキャッシュに保存されても良い (訳注:共有プロキシ上に保存されても良い) のか、明示的にプライベートキャッシュである必要がある (訳注:共有プロキシ上に保存されてはならず、ローカルキャッシュのみ許可される) のか、を指定するには、次のオプションを使用します。
    
    Cache-Control: private
    Cache-Control: public
    
  4. どのリソースが最新であると見做され、いつオリジンサーバから更新されるべきかを指定するには、max-ageを用いてパラメータを指定します。
    Cache-Control: max-age=31536000
  5. 配信の前に、キャッシュされたリソースが最新か検証する必要がある場合は、次のパラメータを用います。
    Cache-Control: must-revalidate

Pragma

Pragmaは旧式のヘッダで、HTTP/1.1で導入されたCache-Controlヘッダと同じ目的で使われますが、Cache-Controlヘッダとは異なり、PragmaヘッダはHTTPリクエスト専用で、レスポンスでは使われません。
ヘッダは今もHTTP/1.1をサポートしないクライアントとの互換性のために使用されています。

関連するHTTPキャッシュヘッダを実装することで、ブラウザのオーバヘッドを減らし、ページレンダリングを高速化することができます。
これにより、ユーザのデジタル体験に良い影響を与えることができます。
キャッシュによる主な影響についてのブログ記事 (英語)もお読み下さい。

圧縮ヘッダ

データ圧縮により、データ転送をより効率化し、帯域の混雑を解消し、ページの読み込みを高速化することができます。
圧縮アルゴリズム (gzipやBrotliなど) は、約70%程度ファイルサイズを削減することができ、現代的で重いWebサイトのパフォーマンスに対して非常に大きな効果があります。

HTTPヘッダを用いて、圧縮を有効化したり、使用可能な圧縮フォーマットを設定したりできます。
設定されるデータ圧縮のタイプによって、ヘッダは大きく2つのカテゴリに分けることができます。

End-to-end ヘッダ

このカテゴリのHTTPヘッダは、end-to-endの圧縮、つまり、サーバでメッセージ本文が圧縮され、クライアントに到達するまで圧縮されたままの圧縮方式の設定のために使われます。
ヘッダはサーバからクライアントに送信されるまで、変更されることがあってはなりません。
ブラウザがHTTPリクエストを行う際、サポートする圧縮アルゴリズムを指定する、Accept-Encodingヘッダを送信します。

Accept-Encoding: gzip

または

Accept-Encoding: gzip, compress, br

サーバはそれから、リクエストされたコンテンツを圧縮してから、Content-Encodingというレスポンスヘッダを付けて送信します。
このヘッダは、ブラウザが指定したアルゴリズムの中からサーバが選択したものを示します。

Content-Encoding: gzip

これらのヘッダに加え、レスポンスにはVaryというヘッダが含まれることもあり、これは圧縮のタイプを決めて後続のリクエストがキャッシュされたリソースのフォーマットを知るために使われたヘッダを示すものです。

Vary: Content-Encoding
End-to-endヘッダ処理

Hop-by-hopヘッダ

Hop-by-hopヘッダは、プロキシ間で再送信されたり、キャッシュされたりしません。
圧縮フォーマットでも、無圧縮のフォーマットでも、サーバからクライアントまでのそれぞれのホップ間で、リソースは送信されます。
これは通常TE、またはTransfer-Encodingヘッダを用いて行われます。

TE: compress, gzip , deflate

または

Transfer-Encoding: gzip, compress
Hop-by-hopヘッダ処理

Webサイトを最適化する際には、データ圧縮を活用することを強くお勧めします。
データの品質に妥協せずにファイルサイズを減らすためには、複雑で高度なアルゴリズムが用いられており、その動作について詳しく知りたい方は、圧縮技術について詳細に書かれた、こちらの投稿を見てみて下さい。

セキュリティヘッダ

HTTPセキュリティヘッダは、HTTPセッションの間のセキュリティポリシを定めるためのもので、リクエストされたコンテンツをどのように処理すればよいか、クライアントに対して示します。
これらのヘッダは、セキュリティ脆弱性に対するパッチをあてる手助けをしたり、データインジェクションやクロスサイトスクリプティングに対する保護を提供したりします。
このカテゴリに属するヘッダをいくつか見ていきましょう。

Content-Security-Policy

Content-Security-Policyヘッダは、ユーザエージェントが読込を許可するリソースやスクリプトの種類を指定するために使われます。
つまり、ブラウザは、サイト管理者が承認した、これらのコンテンツにしかアクセスできないということです。
例えば、スクリプトのダウンロード元のリストを指定することができます。

Content-Security-Policy: script-src https://www.google-analytics.com

Public-Key-Pins

中間者攻撃 (MitM) はPublic-Key-Pinsヘッダを設定することで影響を緩和することが可能です。
暗号鍵をWebサーバに割り当て、偽造証明書を用いた中間者攻撃の可能性を最小化します。


Public-Key-Pins:

  pin-sha256="cUPcluytzOJAhhneDttWpY3oBAkE3h2+soZS7sWs=";

  pin-sha256="M8HztCzM3elUkjdekjkfdppqweHkmjAHKhpGPWE=";

  max-age=5184000; includeSubDomains;

  report-uri=https://www.example.org/

Strict-Transport-Security

Strict-Transport-Securityヘッダは、ブラウザに、HTTPSによってのみWebサーバにアクセスを行うよう強制します。
ヘッダは全てのHTTPリクエストをHTTPSにリダイレクトするため、ユーザは、暗号化され安全なバージョンのサイトのみ見ることになります。

Strict-Transport-Security: max-age=31536000; includeSubDomains

X-Content-Type-Options

このヘッダは、リクエストされたリソースのMIMEタイプを、ブラウザが推測しようとすることを防止します。
X-Content-Type-OptionsがContent-Typeと一緒に使われた際には、MIMEを指定し、MIMEタイプの盗聴を防止します。

X-Content-Type-Options: nosniff

X-Frame-Options

X-Frame-Optionsヘッダは、<iframe>や<object>などのタグの中のコンテンツの読込を許可するかどうかを示します。
例えば、下記のヘッダは、同じサーバからのコンテンツを含むiframeの読込を許可し、異なるサーバからのコンテンツを持つものをブロックします。

X-Frame-Options: SAMEORIGIN

X-XSS-Protection

このヘッダは、クロスサイトスクリプティング(XSS)攻撃に対する、追加のセキュリティ層です。
多くのモダンブラウザは、潜在的なXSSリクエストを検出するデフォルトのフィルタを持っており、x-xss-protectionヘッダによって、これを厳密に強制することができます

x-xss-protection: 1; mode=block