やりたかったこと
ブラウザのキャッシュは便利ですが、要件によっては邪魔になってしまうこともあります。
最新のソースファイルが取れないと困る時もあるし、それでバグが起きては元も子もないですからね…
そこで、あえて今回はキャッシュをさせないようにする設定をしてみます。
実装してみる
今回の環境はタイトル通りNode.js+expressなので、HTTPヘッダをexpressのルーティングで制御すれば出来ます。
自力で設定してもよいのですが、npmにぴったりのモジュールであるnocacheがあるのでそれを使っちゃいましょう。
使い方はこんな感じ。
import express from 'express';
import nocache from 'nocache';
const app = express();
// キャッシュ無効化
app.use(nocache());
以上です。迷うことが無いくらいにシンプル!
後は以降の処理でレスポンスを記述してしまえば、それらは全てキャッシュされないようになります。
まあnocache自体がやっていることは非常に単純で、HTTPヘッダにCache-Control
やExpires
、Surrogate-Control
を設定しているだけです。
とはいえ、じゃあキャッシュを無効化するために何を設定すべきか?と言われるといろいろと情報が新旧入り乱れて正確に考えるのは難しいので、ありがたいですね。(もちろん意味を調べて使うべきではありますが)
しかし、お分かりの通りこれだと全てのキャッシュが無効化されます。
目的は一部のみキャッシュさせないようにするなので、その形で実装してみましょう。
本題の実装
さて、先ほどの例だと全てのルーティングを通してしまったので、一部のみに制限すればよいのです。
ということでやってみました。
import express from 'express';
import nocache from 'nocache';
const app = express();
// キャッシュ無効化
app.use((req, res, next) => {
// img,fontsディレクトリのファイルのみキャッシュさせる
if (/^\/static\/[img|fonts]/.test(req.path) === true) {
next();
}
else {
nocache()(req, res, next);
}
});
今回はリクエストのパスを見て、static/img
orstatic/fonts
ディレクトリはnocache
の処理を通さないようにしました。
まあ特段することも無くそうだねって感じですが、微妙にnocache()(req, res, next);
辺りの記述が変な感じになります。nocacheが返した関数を即実行しているだけなんだけども…
とりあえずこんな感じの実装をすれば、このファイルはキャッシュされると困るけどこれはキャッシュしてほしい!という我儘なケースにも対応できますね。
終わりに
今回の件は振り返ると特に難しいところでもなかったのですが、個人的にキャッシュ無効化した影響でここのパフォーマンス悪いな…でもキャッシュ無効化を外すのもな…と悩んでいたのを解決できたので備忘録も兼ねての記事でした。
キャッシュをどうするかはパフォーマンスひいてはユーザビリティに直結するので、何度も調整しながら進めていくことにします。