文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

やるおと学ぶ、一歩進んだjs・cssのキャッシュ問題の対応

簡単に対応できますよ〜


f:id:treeapps:20180418115102p:plain

web開発で必ず直面する静的ファイルのキャッシュ問題。その解決策の1つして、

<link href="/css/common.css?timestamp=${timestamp}" rel="stylesheet" type="text/css"/>

このように、画面表示毎に動的にタイムスタンプをQueryStringに設定して回避する方法があります。

しかしこれでは画面表示毎にtimestampの変数の値が変わってしまうので、毎回リクエストが走ってしまいます。


これだと確かにキャッシュを回避できるんだけど・・・違う、何か違うんだよなあ・・・


お、そこに疑問を持てるようになったか。成長したな。

そうだ、これだと画面表示毎に新たにjs・cssを取得しにいってしまうんだ。

やりたい事は修正前のjs/cssではなく修正後のjs/cssを取得して欲しいんだ。

だから1回だけ最新ファイルを取得して欲しいわけだな。


できるの?そんなこと。


よく考えてみろやるお。これは既存知識の工夫で解決できる問題なんだ。

通常このcssはデプロイしないと変更されない。つまりデプロイされた時だけ変更されるファイルだよな?ならデプロイされた後だけtimestamp部分が変わってればいいんだ。

環境など

この記事ではjspとantを使った環境をサンプルとして挙げています。

antのreplaceタスクを利用したキャッシュ対策


ビルドツールはantだったよな?(今時antなんて使ってんのかやるお・・)

なら「replaceタスク」を調べてみろ

antにはreplaceタスクという、ファイル内の特定文字列を置換する機能があります。

Replaceタスクはディレクトリベースのタスクで、 選択したファイル中のある文字列を与えられた別の文字列に置換します。

行をまたがるテキストを置換したい場合は、 ネストした 要素を使ってください。

http://www.jajakarta.org/ant/ant-1.6.1/docs/ja/manual/CoreTasks/replace.html


あれ?ファイルの中身を書き換えられるタスクなんてあったんだ!

チョ・マテヨ?という事は、antでビルドする時にtimestamp部分を現在日時をファイルに埋め込めば、ビルドした時にだけ変わるQueryStringになるな!!


そう、それだ!!

あとはその処理をbuild.xmlに書くだけだな!

antタスクでtokenにタイムスタンプを埋め込む


ant内でタイムスタンプを取得するのはtstampで、それをtokenにreplaceする訳だな!

つまり、こうだ!カタカタカタ・・・・ッターーーーン!!

<tstamp>
    <format property="timestamp" pattern="yyyyMMddHHmmss" />
</tstamp>
<replace dir="${view.dir}" token="TIMESTAMP" value="${timestamp}">
    <include name="**/*.jsp" />
</replace>

${view.dir}はjspがあるフォルダを設定して下さい。

jspにreplaceするためのtokenを追加する


build.xmlに設定したtokenの「TIMESTAMP」をjspに書き込んで完了だ。

カタカタカタ・・・・ッターーーーン!!

<link href="/css/common.css?t=TIMESTAMP" rel="stylesheet" type="text/css"/>


うむ。できたな。

この状態でビルドすると、以下のようにjspが置換される。

つまり次回common.cssを修正してビルドするとタイムスタンプが変わるから、修正後のファイルが取得されるわけだ。

<link href="/css/common.css?t=20140830010101" rel="stylesheet" type="text/css"/>

雑感


さっきの例ではreplaceタスクにjspだけを指定してたが、cssやhtmlを指定するとcss内の画像にQueryStringを付加できるし、htmlにも同様に付加できるぞ!

<replace dir="${view.dir}" token="TIMESTAMP" value="${timestamp}">
    <include name="**/*.jsp" />
    <include name="**/*.css" />
    <include name="**/*.html" />
</replace>


あと、antタスクはmavenやgradleからも呼べるから、antに拘る必要はないぞ。


ところでやるお、このjspはどんなサイトで使うのかね?


え?クライアントから依頼されて今作ってるフィッシングサイトっす。