ブラウザキャッシュを利用して少しでもレスポンス向上

こんにちは、開発本部の大西です。

最近の流れから、社内のネットワーク上でなく、インターネット上のSaaS/Cloud環境にintra-martを稼働させてアクセスしたりすることが多くなってきました。

そうすると、環境によってはネットワークの遅延が問題になることがでてくるようになってきました。
また、intra-mart自体もIM共通マスタやIM-WorkflowなどAjaxを多用する機能が増えてきており、
一つの画面を表示するのに、大量のJSファイルやCSSファイルや画像ファイルなどの静的ファイルを
読み込むようになっており、1画面を表示するためのリクエスト数が増加傾向にあります。

現状、この状況を解決する一番簡単な手段として、クライアントのブラウザのキャッシュ機能を有効活用することで、見かけ上のレスポンスを向上させることができます。

つまり、ブラウザにキャッシュされては困る、intra-mart上のプログラム上で生成されるコンテンツ自体はキャッシュさせずに、変更される頻度が低いクライアントサイドのJavaScriptファイル、CSSファイル、画像ファイルをブラウザ側にキャッシュさせ、毎回サーバ側に取得させなくすることで、ブラウザからのリクエスト数を減少させて、サーバの負荷を低減させ、見かけ上のレスポンスも向上させることが可能です。

具体的な対応方法としては、

WebPlatformで、ResinをWeb/APサーバとして利用している場合

AppRuntimeのconf/http.xmlの「<web-app id="/imart" ・・・」の<web-app>タグ内に
以下の設定を追記してください。

        <filter filter-name='expires-1D' filter-class='com.caucho.filters.ExpiresFilter'>
            <init>
              <cache-time>1D</cache-time>
            </init>
        </filter>
        <filter-mapping url-pattern='*.js'  filter-name='expires-1D'/>
        <filter-mapping url-pattern='*.css' filter-name='expires-1D'/>
        <filter-mapping url-pattern='*.png' filter-name='expires-1D'/>
        <filter-mapping url-pattern='*.gif' filter-name='expires-1D'/>
        <filter-mapping url-pattern='*.jpg' filter-name='expires-1D'/>

この設定で、拡張子が、js,css,png,gif.jpgの静的コンテンツが1D = 1日間(24時間)、ブラウザにキャッシュされ、キャッシュが存在した場合は、ブラウザはキャッシュを利用します。

また、これに合わせて、転送時のファイルサイズをGzip圧縮で圧縮する設定をあわせて行うことで、転送時間を抑えることができ、非常に効果的ですので、上記設定と合わせて設定していただくことを推奨致します。

GZIP圧縮の設定は、上記と同じ<web-app>タグ内に

        <filter filter-name="gzip" filter-class="com.caucho.filters.GzipFilter"/>
        <filter-mapping url-pattern='*.js'  filter-name='gzip'/>
        <filter-mapping url-pattern='*.css' filter-name='gzip'/>
        <filter-mapping url-pattern='*.png' filter-name='gzip'/>
        <filter-mapping url-pattern='*.gif' filter-name='gzip'/>
        <filter-mapping url-pattern='*.jpg' filter-name='gzip'/>

を記載することで、APPサーバ側でGZIP圧縮することが可能になります。

Apacheを利用している場合

Apacheのconf/http.confに

        ExpiresActive On
        <IfModule mod_expires.c>
           <FilesMatch "\.(css|js)$">
              ExpiresDefault "access plus 1 days"
           </FilesMatch>
           <FilesMatch "\.(gif|jpeg|jpg|png)$">
              ExpiresDefault "access plus 1 days"
           </FilesMatch>
           ExpiresByType text/css "access plus 1 days"
           ExpiresByType application/x-javascript "access plus 1 days"
           ExpiresByType image/jpeg "access plus 1 days"
           ExpiresByType image/gif "access plus 1 days"
           ExpiresByType image/png "access plus 1 days"
        </IfModule>

を記載することで、上記と同じ動作になります。
なお、GZIP圧縮の設定は以下になります。

        <IfModule mod_deflate.c>
           SetOutputFilter DEFLATE
           BrowserMatch ^Mozilla/4 gzip-only-text/html
           BrowserMatch ^Mozilla/4\.0[678] no-gzip
           BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
           SetEnvIfNoCase Request_URI "\.(?:gif|jpe?g|png|zip|lzh)$" no-gzip dont-vary
           Header append Vary User-Agent env=!dont-vary

        DeflateCompressionLevel 5
            AddOutputFilterByType DEFLATE text/html
            AddOutputFilterByType DEFLATE text/html; charset=Windows-31J
            AddOutputFilterByType DEFLATE text/plain
            AddOutputFilterByType DEFLATE text/css
            AddOutputFilterByType DEFLATE text/xml
            AddOutputFilterByType DEFLATE application/x-javascript
            AddOutputFilterByType DEFLATE application/xml
            AddOutputFilterByType DEFLATE application/rdf+xml
        </IfModule>

参考までに、私のローカル環境で確認したところ、
IM-Workflowの申請画面の根回しメールにある検索リンクを押下してから、
ユーザ検索画面が表示されるまでのリクエスト数とレスポンスタイムは以下のようになりました。

上記設定なし             :リクエスト数:142 レスポンスタイム:2.36秒
上記設定あり(1回目のリクエスト) :リクエスト数:117 レスポンスタイム:1.49秒
上記設定あり(2回目のリクエスト) :リクエスト数:12  レスポンスタイム:0.65秒

とローカル環境でも効果はありますので、どの環境でも効果はあると思います。

なお、注意点として、上記に説明している通り、上記設定を行った場合、静的コンテンツを
指定期間ブラウザにキャッシュすることになりますので、今後のパッチの適用等でCSSやJSファイルに変更があった場合にパッチ適用しても有効にならず、不具合が発生する場合がありますので、その場合は、ブラウザのキャッシュを消去して頂く必要がありますので、ご注意ください。