著者はCOVID-19救済基金を選択し、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

Webサイトの読み込みが速いほど、訪問者が滞在する可能性が高くなります。 ウェブサイトが画像でいっぱいで、バックグラウンドでロードされたスクリプトによって実行されるインタラクティブなコンテンツである場合、ウェブサイトを開くことは簡単な作業ではありません。 これは、サーバーから1つずつ多くの異なるファイルを要求することで構成されます。 これらのリクエストの量を最小限に抑えることは、Webサイトを高速化する1つの方法です。

Webサイトのパフォーマンスを向上させる1つの方法は、ブラウザキャッシングです。 ブラウザのキャッシュは、サーバーに何度も要求する代わりに、ダウンロードしたファイルのローカルバージョンを再利用できることをブラウザに通知します。 これを行うには、ブラウザに動作方法を指示する新しいHTTP応答ヘッダーを導入する必要があります。

Nginxのヘッダーモジュールは、ブラウザのキャッシュを実現するのに役立ちます。 このモジュールを使用して、任意のヘッダーを応答に追加できますが、その主な役割は、キャッシュヘッダーを適切に設定することです。 このチュートリアルでは、Nginxのヘッダーモジュールを使用してブラウザのキャッシュを実装します。

前提条件

このチュートリアルに従うには、次のものが必要です。

ステップ1—テストファイルの作成

このステップでは、デフォルトのNginxディレクトリにいくつかのテストファイルを作成します。 後でこれらのファイルを使用して、Nginxのデフォルトの動作を確認し、ブラウザーのキャッシュが機能していることをテストします。

ネットワーク上で提供されるファイルの種類を推測するために、Nginxはファイルの内容を分析しません。 それは法外に遅いでしょう。 代わりに、ファイル拡張子を検索して、ファイルのMIMEタイプを判別します。これはその目的を示します。

この動作のため、テストファイルの内容は関係ありません。 ファイルに適切な名前を付けることで、たとえば、完全に空のファイルの1つが画像で、もう1つがスタイルシートであるとNginxを騙して考えることができます。

truncateを使用して、デフォルトのNginxディレクトリにtest.htmlという名前のファイルを作成します。 この拡張機能は、それがHTMLページであることを示します。

  1. sudo truncate -s 1k /usr/share/nginx/html/test.html

同じ方法でさらにいくつかのテストファイルを作成しましょう。1つはjpg画像ファイル、1つはcssスタイルシート、もう1つはjsJavaScriptファイルです。

  1. sudo truncate -s 1k /usr/share/nginx/html/test.jpg
  2. sudo truncate -s 1k /usr/share/nginx/html/test.css
  3. sudo truncate -s 1k /usr/share/nginx/html/test.js

次のステップは、作成したばかりのファイルを使用して、新規インストールでキャッシュ制御ヘッダーを送信することに関してNginxがどのように動作するかを確認することです。

ステップ2—デフォルトの動作を確認する

デフォルトでは、すべてのファイルのデフォルトのキャッシュ動作は同じです。 これを調べるために、手順1で作成したHTMLファイルを使用しますが、これらのテストは任意のサンプルファイルで実行できます。

それでは、test.htmlに、ブラウザーが応答をキャッシュする時間に関する情報が提供されているかどうかを確認しましょう。 次のコマンドは、ローカルのNginxサーバーからファイルを要求し、応答ヘッダーを表示します。

  1. curl -I http://localhost/test.html

いくつかのHTTP応答ヘッダーが表示されます。

Output: Nginx response headers
HTTP/1.1 200 OK Server: nginx/1.14.1 Date: Thu, 04 Feb 2021 18:23:09 GMT Content-Type: text/html Content-Length: 1024 Last-Modified: Thu, 04 Feb 2021 18:22:39 GMT Connection: keep-alive ETag: "601c3b6f-400" Accept-Ranges: bytes

最後から2番目の行には、ETagヘッダーがあります。このヘッダーには、要求されたファイルのこの特定のリビジョンの一意の識別子が含まれています。 前のcurlコマンドを繰り返し実行すると、まったく同じETag値が見つかります。

Webブラウザーを使用している場合、ブラウザーが同じファイルを再度要求するとき(たとえば、ページを更新するとき)に、ETag値が保存され、If-None-Match要求ヘッダーとともにサーバーに返送されます。 。

次のコマンドを使用して、コマンドラインでこれをシミュレートできます。 このコマンドのETag値を、前の出力のETag値と一致するように変更してください。

  1. curl -I -H 'If-None-Match: "601c3b6f-400"' http://localhost/test.html

これで、応答が異なります。

Output: Nginx response headers
HTTP/1.1 304 Not Modified Server: nginx/1.14.1 Date: Thu, 04 Feb 2021 18:24:05 GMT Last-Modified: Thu, 04 Feb 2021 18:22:39 GMT Connection: keep-alive ETag: "601c3b6f-400"

今回、Nginxは 304 NotModifiedで応答します。 ネットワーク経由でファイルを再度送信することはありません。 代わりに、ローカルでダウンロード済みのファイルを再利用できることをブラウザに通知します。

これはネットワークトラフィックを減らすので便利ですが、優れたキャッシュパフォーマンスを達成するには十分ではありません。 ETagの問題は、ブラウザが常にサーバーにリクエストを送信して、キャッシュされたファイルを再利用できるかどうかを尋ねることです。 サーバーがファイルを再送信する代わりに304で応答したとしても、要求を行って応答を受信するのに時間がかかります。

次のステップでは、headersモジュールを使用してキャッシュ制御情報を追加します。 これにより、ブラウザは、サーバーに明示的にキャッシュするかどうかを明示的に要求することなく、一部のファイルをローカルにキャッシュできるようになります。

ステップ3—Cache-ControlおよびExpiresヘッダーの構成

ETagファイル検証ヘッダーに加えて、Cache-ControlExpiresの2つのキャッシュ制御応答ヘッダーがあります。 Cache-Controlは新しいバージョンであり、Expiresよりも多くのオプションがあり、キャッシュ動作をより細かく制御したい場合に一般的に便利です。

これらのヘッダーが設定されている場合、要求されたファイルを再度要求することなく、一定期間(永久を含む)ローカルに保持できることをブラウザーに通知できます。 ヘッダーが設定されていない場合、ブラウザは常にサーバーにファイルを要求し、 200OKまたは304NotModifiedの応答を期待します。

ヘッダーモジュールを使用して、これらのHTTPヘッダーを設定できます。 ヘッダーモジュールはコアNginxモジュールです。つまり、使用するために個別にインストールする必要はありません。

ヘッダーモジュールを追加するには、vi vi の簡単な紹介)またはお気に入りのテキストエディターでデフォルトのサーバーブロックNginx構成ファイルを開きます。

  1. sudo vi /etc/nginx/nginx.conf

server構成ブロックを見つけます。

/etc/nginx/nginx.conf
. . .
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name  _;
    root         /usr/share/nginx/html;
. . .

ここに次の2つの新しいセクションを追加します。1つはserverブロックの前にあり、さまざまなファイルタイプをキャッシュする時間を定義し、もう1つはその中にキャッシュヘッダーを適切に設定します。

変更された/etc/nginx/nginx.conf
. . .
# Expires map
map $sent_http_content_type $expires {
    default                    off;
    text/html                  epoch;
    text/css                   max;
    application/javascript     max;
    ~image/                    max;
    ~font/                     max;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name  _;
    root         /usr/share/nginx/html;

    expires $expires;
. . .

serverブロックの前のセクションは、新しいmapブロックであり、ファイルの種類とその種類のファイルをキャッシュする期間の間のマッピングを定義します。

このマップでは、いくつかの異なる設定を使用しています。

  • デフォルト値はoffに設定されており、キャッシュ制御ヘッダーは追加されません。 これはコンテンツにとって安全な賭けです。キャッシュがどのように機能するかについての特別な要件はありません。

  • text/htmlの場合、値をepochに設定します。 これは特別な値であり、明示的にキャッシュが発生しないため、ブラウザはWebサイト自体が最新であるかどうかを常に確認します。

  • スタイルシートおよびJavaScriptファイルであるtext/cssおよびapplication/javascriptの場合、値をmaxに設定します。 これは、ブラウザがこれらのファイルをできるだけ長くキャッシュし、通常これらのファイルが多数あることを考えると、リクエストの数を大幅に減らすことを意味します。

  • 最後の2つの設定は、~image/~font/の設定です。これらは、MIMEにimage/またはfont/を含むすべてのファイルタイプに一致する正規表現です。タイプ名(image/jpgimage/pngfont/woff2など)。 スタイルシートと同様に、Webサイトの画像とWebフォントの両方を安全にキャッシュして、ページの読み込み時間を短縮できるため、これもmaxに設定します。

注:これらは、Webサイトで使用される最も一般的なMIMEタイプのほんの一例です。 一般的なMIMEタイプサイトでそのようなタイプのより広範なリストに精通し、自分のケースで役立つと思われる他のタイプをマップに追加できます。

サーバーブロック内で、expiresディレクティブ(ヘッダーモジュールの一部)がキャッシュ制御ヘッダーを設定します。 マップに設定されている$expires変数の値を使用します。 このように、結果のヘッダーはファイルタイプによって異なります。

ファイルを保存して閉じ、終了します。

新しい構成を有効にするには、Nginxを再起動します。

  1. sudo systemctl restart nginx

次に、新しい構成が機能することを確認しましょう。

ステップ4—ブラウザキャッシュのテスト

テストHTMLファイルに対して前と同じリクエストを実行します。

  1. curl -I http://localhost/test.html

今回は反応が異なります。 2つの追加のHTTP応答ヘッダーが表示されます。

Nginx応答ヘッダー
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Thu, 04 Feb 2021 18:28:19 GMT
Content-Type: text/html
Content-Length: 1024
Last-Modified: Thu, 04 Feb 2021 18:22:39 GMT
Connection: keep-alive
ETag: "601c3b6f-400"
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Cache-Control: no-cache
Accept-Ranges: bytes

Expiresヘッダーは過去の日付を示し、Cache-Controlno-cacheで設定されます。これは、ファイルの新しいバージョンがあるかどうかを常にサーバーに確認するようにブラウザーに指示します(以前のように、ETagヘッダーを使用します)。

テスト画像ファイルとの応答に違いがあります。

  1. curl -I http://localhost/test.jpg

新しい出力に注意してください。

Nginx応答ヘッダー
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Thu, 04 Feb 2021 18:29:05 GMT
Content-Type: image/jpeg
Content-Length: 1024
Last-Modified: Thu, 04 Feb 2021 18:22:42 GMT
Connection: keep-alive
ETag: "601c3b72-400"
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Cache-Control: max-age=315360000
Accept-Ranges: bytes

この場合、Expiresは遠い将来の日付を示し、Cache-Controlにはmax-age情報が含まれています。これは、ファイルを秒単位でキャッシュできる時間をブラウザに通知します。 これにより、ダウンロードされた画像を可能な限りキャッシュするようにブラウザに指示されるため、この画像がその後表示されると、ローカルキャッシュが使用され、サーバーにリクエストが送信されなくなります。

JavaScriptファイルとスタイルシートファイルの両方にキャッシュヘッダーが設定されているため、結果はtest.jstest.cssの両方で同様になるはずです。

これは、キャッシュ制御ヘッダーが適切に構成されていることを意味し、ブラウザーのキャッシュによるパフォーマンスの向上とサーバー要求の減少により、Webサイトが恩恵を受けます。 Webサイトのコンテンツに基づいてキャッシュ設定をカスタマイズする必要がありますが、この記事のデフォルトから始めるのが妥当です。

結論

ヘッダーモジュールを使用して、任意のヘッダーを応答に追加できますが、キャッシュ制御ヘッダーを適切に設定することは、その最も有用なアプリケーションの1つです。 これにより、特に携帯電話会社のネットワークなど、待ち時間の長いネットワークで、Webサイトユーザーのパフォーマンスが向上します。 また、検索エンジンでより良い結果が得られ、速度テストが結果に反映される可能性があります。 ブラウザのキャッシュヘッダーを設定することは、GoogleのPageSpeedおよび同様のパフォーマンステストツールからの重要な推奨事項です。

ヘッダーモジュールの詳細については、Nginxの公式ヘッダーモジュールドキュメントをご覧ください。