Googleはなぜモバイルに力を入れるのか?これからのWebパフォーマンスで注力すべきポイント | HTML5Experts.jpを読んで、「そういえばこのブログはGoogleのPageSpeed Insightsでチェックしていたかな?」と思い、早速分析にかけてみました。
分析結果を確認すると、「修正を考慮」の項で"画像やCSSファイルのHTTPヘッダー内で有効期日を設定するとよい"という趣旨のアドバイスが表示されました。そういえば、まだデザイン等を修正するかもしれないので落ち着くまでExpiresヘッダの設定はしないでおこうと考えていました。サイトロゴの作成も完了し、デザインもひとまず満足しているので、早速nginxの設定を変更し、Expiresヘッダを送信するようにしました。
URLフィンガープリントを利用してCSS変更時の対策を行う
CSSだけは時々変更を行うことがあります。すぐに反映されないと困るのでどうしようかと考えつつ「ブラウザのキャッシュを活用する」を読んでいると、「URL フィンガープリントの使用」の項にヒントがありました。
ときどき変更されるリソースの場合、サーバー上でリソースが変更され、サーバーがブラウザに新しいバージョンが提供されたことを通知するまで、ブラウザでリソースをキャッシュしておくことができます。リソースの各バージョンに一意の URL を指定すると、この方法を実現できます。たとえば、「my_stylesheet.css」というリソースがあるとします。このファイル名を「my_stylesheet_fingerprint.css」に変更できます。リソースが変更されると、フィンガープリントも変更されるため、URL も変わります。URL が変更されるとすぐに、ブラウザはリソースの再取得を強制されます。フィンガープリントを使用すると、頻繁に変更されるリソースでも、有効期限をそれより先の方の日付に設定できるようになります。
フィンガープリントの一般的な方法として、ファイルのコンテンツのハッシュをコード化した 128 ビットの 16 進数が使用されます。
"url fingerprint"でGoogle検索を行いページを見ているとGruntのタスクが出てきたので、「Gruntで自動化すれば良いのか」と気付きました。ただ、今のGruntfile.coffeeに新たなタスクを追加すると、CSS関連のタスクが色々あって分かりづらそうなので、gulpに移行してgulp-revをインストールし、下記のようにgulpfile.coffeeを書きました(一部抜粋)。やはりgulpで書く方が分かりやすい印象です。
# Path Settings
basepath = '../htdocs/'
paths =
styles:
src: basepath + '_scss/'
dest: basepath + 'css/'
images:
src: basepath + '**/*.{png,jpg,svg}'
# Read Modules
gulp = require 'gulp'
path = require 'path'
plugins = require('gulp-load-plugins')()
# Tasks
gulp.task 'styles', ->
gulp.src paths.styles.src + 'basic.scss'
.pipe plugins.rubySass
style: 'compressed'
sourcemap: false
precision: 3
loadPath: path.join(__dirname) + '/' + paths.styles.src
.pipe plugins.autoprefixer 'last 2 version', 'ie 9', 'ie 8', 'Firefox ESR'
.pipe if plugins.util.env.prod then plugins.rev() else plugins.util.noop()
.pipe gulp.dest paths.styles.dest
gulp.task 'webserver', ->
gulp.src basepath
.pipe plugins.webserver
livereload: true
host: '0.0.0.0'
port: 3501
gulp.task 'watch', ->
gulp.watch paths.styles.src + '*.scss', ['styles']
return
gulp.task 'default', [
'webserver'
'styles'
'watch'
]
これにより、通常はgulpコマンドで制作を行い、作業完了時はgulp styles --prodコマンドでコンパイルを行い、"basic-ea73a21c.css"のようなフィンガープリント付きのファイルを出力するようにしました(128ビットの16進数にはなっていないものの、ひとまずこれで...)。
link要素で指定しているCSS名のファイル名も変更が必要ですが、gulp-revのintegration guideなどにヒントがありそうです。このサイトはMTなので、rev-manifest.jsonとMTのプラグインで対応すれば良いかなと考えています。