0. 前提

  • 環境などの前提条件は前回の1から3と同じです。

    今回は教科書の[1. Reduce number of HTTP requests]-[Use Browser Cache]をやってみました。

    修正が少ない静的ファイルはブラウザキャッシュの期間を延ばし、2回目以降のアクセスはキャッシュから読み込むことで速度向上につなげます。

    作業は下記の2点です。

    (1) キャッシュ期間延長

     Webサーバーの設定でjs、cssのブラウザ・キャッシュ期間を延ばします。

    (2) ファイル名のユニーク化

     上記1によって修正がすぐに反映されないという状況を避けるため、ファイル名に修正ごとのハッシュ値を付けてキャッシュが効かないようにします。(gulpの機能を利用)

1. キャッシュ期間延長

  • nginxの設定ファイルにjs、cssの設定とキャッシュ期間を追記しました。

    記述が冗長なのは追って別の書き方を調べたいと思います。

    server {
            listen 443 ssl;
            server_name [ドメイン名];
            ssl_certificate [ファイルパス];
            ssl_certificate_key [ファイルパス];
    
            location / {
                proxy_pass http://[ホスト名]:[ポート番号];
                proxy_set_header X-Real-IP  $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto https;
                proxy_set_header X-Forwarded-Port 443;
                proxy_set_header Host $host;
            }
    
            # --- css/jsの指定を追加。 ---
            location ~* .(css|js)$ {
                proxy_pass http://[ホスト名]:[ポート番号];
                proxy_set_header X-Real-IP  $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto https;
                proxy_set_header X-Forwarded-Port 443;
                proxy_set_header Host $host;
                # キャッシュ期間を設定。
                expires 365d;
            }
            # --- css/jsの指定を追加。 ---
    }
    

    ChromeのDeveloper Toolsで見て、Expiresヘッダーの追加とjs、cssがキャッシュから読み込まれていることを確認します。(下図オレンジの枠線)

    (注)キャプチャのタイミングに数日のズレあり、また下記2まで対応した後のためファイル名も変更済み。

    • 変更前

    変更前

    • 変更後

    変更後

2. ファイル名のユニーク化

  • 作業にかかろうと思ったら、gulpコマンドが実行できなくなっていたので、それも記載しておきます。

    Webアプリのルートディレクトリでgulpを実行すると下記メッセージが表示されました。

    $ gulp
    -bash: gulp: command not found
    

    前回設定したnodebrewへのパスが消えているようです。

    $ echo $PATH | grep nodebrew
    $
    
    $ source ~/.bashrc
    

    sourceで再読み込みすればgulpコマンドも使えるのですが、毎回やるのは面倒です。

    Macだと.bashrcがターミナル起動時に読み込まれないようなので、.bash_profileに設定します。

    $ vim ~/.bash_profile
    

    末尾にこれを追記します。

    if [ -f ~/.bashrc ]; then
      . ~/.bashrc
    fi
    
  • さて、気を取り直して本題です。

    gulpファイル操作

    gulpを使って上記のファイル操作を行います。(*1)

    ① これから出力するファイルを予め削除。

    ② jsファイルを圧縮、結合。

    ③ ファイル名にハッシュ値を付け、さらに変換内容をrev-manifest.jsonに記録。

    ④ rev-manifest.jsonを元に、オリジナルファイル(simple-cal.orgディレクトリ配下)内のjsファイル名を置換したファイルをViewsディレクトリに配置。この時、オリジナルは変更されません。また、プログラムから使用されているのはViewsディレクトリ配下のものだけです。

    (*1)

    実際はsimple-calの下にcssディレクトリもありますがスペースの都合で省略。
    ディレクトリ構造はフレームワークに依存するので、適宜読み替えて下さい。
    拡張子stencilはHTMLを生成するためのViewファイルです。
    

    この処理を行うため、下記のgulpfile.jsをWebアプリのルートディレクトリに置き、前回から追加で必要なプラグインをインストールした後、gulpコマンドを実行します。

    $ npm install --save-dev gulp-clean gulp-rev gulp-rev-replace
    $ 
    $ gulp
    

    各タスクの関連については、下図を参照して下さい。

    前回から改善して、タスクの同期・非同期を明確にしました。

    矢印の集約が同期ポイントで、例えばrev-replaceはjs-revとcss-revの完了を待ってから開始します。

    gulpタスクフロー

  • その他として、僕が使っているフレームワークのようにViewの拡張子(.stencil)が一般的ではない場合、gulp-rev-replaceで置換できないということが起きます。

    これについては仕様を確認した後、replaceInExtensionsオプションの指定で解決できました。(上記gulpfile.jsに記載済み)

7.結果

  • ここまでやって前後の比較をしたところ、Chromeで下記の結果になりました。

    やはり転送量が大きく削減されていますね。

    Before After
    Load
    (5回の平均)
    2.7秒 1.9秒
    転送量 451KB 34KB
    リクエスト数 19 19