前書き
ウェブサイトの読み込みが速いほど、訪問者は滞在する可能性が高くなります。 ウェブサイトがバックグラウンドでロードされたスクリプトによって実行される画像とインタラクティブなコンテンツでいっぱいの場合、ウェブサイトを開くことは簡単な作業ではありません。 サーバーから多くの異なるファイルを1つずつ要求することで構成されます。 これらのリクエストの量を最小限に抑えることは、Webサイトを高速化する1つの方法です。
これはさまざまな方法で実行できますが、実行する最も重要な手順の1つは、browser cachingを構成することです。 これは、一度ダウンロードしたファイルをサーバーに何度も要求する代わりに、ローカルコピーから再利用できることをブラウザーに伝えています。 これを行うには、ブラウザに動作を指示する新しいHTTP応答ヘッダーを導入する必要があります。
これは、Nginxのヘッダーモジュールが作用する場所です。 このモジュールを使用して、任意のヘッダーを応答に追加できますが、その主な役割は、キャッシュヘッダーを適切に設定することです。 このチュートリアルでは、Nginxのヘッダーモジュールを使用してブラウザーのキャッシュを実装する方法を見ていきます。
前提条件
このチュートリアルを実行するには、次のものが必要です。
-
sudo非rootユーザーを含むthis initial server setup tutorialでセットアップされた1つのCentOS7サーバー。
-
How To Install Nginx on CentOS 7 tutorialに従ってサーバーにインストールされたNginx。
この記事では、ヘッダーモジュールに加えて、Nginxのマップモジュールも使用します。 マップモジュールの詳細については、How To Use Nginx’s map Module on CentOS 7を参照してください。
[[step-1 -—- creating-test-files]] ==ステップ1—テストファイルの作成
このステップでは、デフォルトのNginxディレクトリにいくつかのテストファイルを作成します。 これらのファイルを後で使用して、Nginxのデフォルトの動作を確認し、ブラウザのキャッシュが機能していることをテストします。
ネットワーク経由で提供されるファイルの種類を決定するために、Nginxはファイルの内容を分析しません。それは法外に遅いでしょう。 代わりに、ファイル拡張子を検索して、ファイルの目的を示すファイルのMIME typeを判別します。
この動作のため、テストファイルの内容は無関係です。 ファイルに適切な名前を付けることにより、Nginxをだまして、たとえば、1つの完全に空のファイルは画像で、もう1つはスタイルシートであると考えることができます。
truncate
を使用して、デフォルトのNginxディレクトリにtest.html
という名前のファイルを作成します。 この拡張機能は、HTMLページであることを示しています。
sudo truncate -s 1k /usr/share/nginx/html/test.html
同じ方法でさらにいくつかのテストファイルを作成しましょう。1つはjpg
画像ファイル、1つはcss
スタイルシート、もう1つはjs
JavaScriptファイルです。
sudo truncate -s 1k /usr/share/nginx/html/test.jpg
sudo truncate -s 1k /usr/share/nginx/html/test.css
sudo truncate -s 1k /usr/share/nginx/html/test.js
次のステップでは、作成したばかりのファイルを使用して、新規インストールでキャッシュコントロールヘッダーを送信することに関するNginxの動作を確認します。
[[step-2 -—- checking-the-default-behavior]] ==ステップ2—デフォルトの動作を確認する
デフォルトでは、すべてのファイルに同じデフォルトのキャッシュ動作が設定されます。 これを調べるために、ステップ1で作成したHTMLファイルを使用しますが、これらのテストは任意のサンプルファイルで実行できます。
それでは、ブラウザが応答をキャッシュする時間に関する情報がtest.html
に提供されているかどうかを確認しましょう。 次のコマンドは、ローカルのNginxサーバーにファイルを要求し、応答ヘッダーを表示します。
curl -I http://localhost/test.html
いくつかのHTTP応答ヘッダーが表示されるはずです。
Output: Nginx response headersHTTP/1.1 200 OK
Server: nginx/1.10.1
Date: Thu, 06 Oct 2016 10:21:04 GMT
Content-Type: text/html
Content-Length: 1024
Last-Modified: Thu, 06 Oct 2016 10:20:44 GMT
Connection: keep-alive
ETag: "57f6257c-400"
Accept-Ranges: bytes
最後から2番目の行には、ETag
ヘッダーがあります。このヘッダーには、要求されたファイルのこの特定のリビジョンの一意の識別子が含まれています。 前のcurl
コマンドを繰り返し実行すると、まったく同じETag
値が表示されます。
Webブラウザーを使用している場合、ブラウザーが同じファイルを再度要求するとき(たとえば、ページを更新するとき)に、ETag
値が保存され、If-None-Match
要求ヘッダーとともにサーバーに返送されます。
次のコマンドを使用して、コマンドラインでこれをシミュレートできます。 このコマンドのETag
値を、前の出力のETag
値と一致するように変更してください。
curl -I -H 'If-None-Match: "57f6257c-400"' http://localhost/test.html
応答は異なるようになります。
Output: Nginx response headersHTTP/1.1 304 Not Modified
Server: nginx/1.10.1
Date: Thu, 06 Oct 2016 10:21:40 GMT
Last-Modified: Thu, 06 Oct 2016 10:20:44 GMT
Connection: keep-alive
ETag: "57f6257c-400"
今回は、Nginxは304 Not Modifiedで応答します。 ネットワーク経由でファイルを再度送信することはありません。代わりに、既にローカルにダウンロードしたファイルを再利用できることをブラウザに伝えます。
これはネットワークトラフィックを削減するので便利ですが、優れたキャッシュパフォーマンスを達成するには十分ではありません。 ETag
の問題は、ブラウザーalwaysがサーバーに要求を送信して、キャッシュされたファイルを再利用できるかどうかを尋ねることです。 サーバーは、ファイルを再度送信する代わりに304で応答しますが、要求を作成して応答を受信するにはまだ時間がかかります。
次のステップでは、ヘッダーモジュールを使用して、キャッシュ制御情報を追加します。 これにより、ブラウザは、サーバーにキャッシュしても問題ないかどうかを明示的に確認することなく、いくつかのファイルをローカルにキャッシュします。
[[step-3 -—- configuring-cache-control-and-expires-headers]] ==ステップ3—Cache-ControlおよびExpiresヘッダーの構成
ETag
ファイル検証ヘッダーに加えて、Cache-Control
とExpires
の2つのキャッシュ制御応答ヘッダーがあります。 Cache-Control
は新しいバージョンであり、Expires
よりも多くのオプションがあり、キャッシュ動作をより細かく制御したい場合は一般的に便利です。
これらのヘッダーが設定されている場合、リクエストされたファイルは、再度リクエストすることなく、一定時間(永久に含む)ローカルに保持できることをブラウザに伝えることができます。 ヘッダーが設定されていない場合、ブラウザーは常にサーバーにファイルを要求し、200 OKまたは304 Not Modifiedの応答を期待します。
ヘッダーモジュールを使用して、これらのHTTPヘッダーを設定できます。 ヘッダーモジュールはコアNginxモジュールです。つまり、使用するために個別にインストールする必要はありません。
ヘッダーモジュールを追加するには、デフォルトのサーバーブロックNginx構成ファイルをvi
(ここではshort introduction to vi
)またはお気に入りのテキストエディターで開きます。
sudo vi /etc/nginx/nginx.conf
次のようなserver
構成ブロックを見つけます。
/etc/nginx/nginx.conf
. . .
server {
listen 80 default_server;
listen [::]:80 default_server;
. . .
ここに次の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;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
expires $expires;
. . .
server
ブロックの前のセクションは、新しいmap
ブロックであり、ファイルタイプとその種類のファイルをキャッシュする期間との間のマッピングを定義します。
このマップではいくつかの異なる設定を使用しています:
-
デフォルト値は
off
に設定されており、キャッシュ制御ヘッダーは追加されません。 キャッシュがどのように機能するかについての特別な要件はありません。 -
text/html
の場合、値をepoch
に設定します。 これは、キャッシュを明示的に行わない特別な値であり、Webサイト自体が最新かどうかを常にブラウザに確認させます。 -
スタイルシートとJavascriptファイルである
text/css
とapplication/javascript
の場合、値をmax
に設定します。 これは、ブラウザがこれらのファイルをできる限りキャッシュすることを意味し、通常これらのファイルが多数あるため、要求の量を大幅に削減します。 -
最後の設定は
~image/
用です。これは、MIME type名にimage/
を含むすべてのファイルタイプ(image/jpg
やimage/png
など)に一致する正規表現です。 。 スタイルシートのように、安全にキャッシュできるWebサイトには多くの画像があるため、これもmax
に設定します。
サーバーブロック内で、expires
ディレクティブ(ヘッダーモジュールの一部)がキャッシュ制御ヘッダーを設定します。 マップに設定された$expires
変数の値を使用します。 この方法では、結果のヘッダーはファイルの種類によって異なります。
ファイルを保存して閉じ、終了します。
新しい構成を有効にするには、Nginxを再起動します。
sudo systemctl restart nginx
次に、新しい構成が機能することを確認します。
[[step-4 -—- testing-browser-caching]] ==ステップ4—ブラウザのキャッシュをテストする
テストHTMLファイルに対して、以前と同じリクエストを実行します。
curl -I http://localhost/test.html
今回は応答が異なります。 2つの追加のHTTP応答ヘッダーが表示されます。
Nginx応答ヘッダー
HTTP/1.1 200 OK
Server: nginx/1.10.1
Date: Thu, 06 Oct 2016 10:24:42 GMT
Content-Type: text/html
Content-Length: 1024
Last-Modified: Thu, 06 Oct 2016 10:20:44 GMT
Connection: keep-alive
ETag: "57f6257c-400"
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Cache-Control: no-cache
Accept-Ranges: bytes
Expires
ヘッダーは過去の日付を示し、Cache-Control
はno-cache
で設定されます。これは、ファイルの新しいバージョンがあるかどうかを常にサーバーに確認するようにブラウザーに指示します(%を使用) (t3)sヘッダー(前と同じ)。
テスト画像ファイルとの差分応答が表示されます。
curl -I http://localhost/test.jpg
Nginx応答ヘッダー
HTTP/1.1 200 OK
Server: nginx/1.10.1
Date: Thu, 06 Oct 2016 10:25:02 GMT
Content-Type: image/jpeg
Content-Length: 1024
Last-Modified: Thu, 06 Oct 2016 10:20:46 GMT
Connection: keep-alive
ETag: "57f6257e-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.js
とtest.css
の両方で同様になるはずです。
これは、キャッシュ制御ヘッダーが適切に構成されていることを意味し、Webサイトはパフォーマンスの向上と、ブラウザーのキャッシュによるサーバーリクエストの減少の恩恵を受けます。 Webサイトのコンテンツに基づいてキャッシュ設定をカスタマイズする必要がありますが、この記事のデフォルトは開始するのに妥当な場所です。
結論
headersモジュールを使用して、任意のヘッダーを応答に追加できますが、キャッシュコントロールヘッダーを適切に設定することは、最も便利なアプリケーションの1つです。 特にモバイルキャリアネットワークのように待ち時間が長いネットワークで、Webサイトユーザーのパフォーマンスが向上します。 また、速度テストを結果に組み込む検索エンジンでのより良い結果につながる可能性があります。 ブラウザのキャッシュヘッダーの設定は、GoogleのPageSpeedテストツールからの主要な推奨事項の1つです。
ヘッダーモジュールの詳細については、in Nginx’s official headers module documentationを参照してください。