AWS S3のキャッシュコントロール(cache control)を一括で書き換える方法

このサイトの画像などのリソースは、サーバーの負荷を軽くする のと、 リソースの管理を簡単にする ことを狙って、ほとんどAWS S3から配信(※1) しています。

※1 現在はaws s3からの配信は行っておりません

そして、今日ブラウザで自分のサイトを開く速度が遅いなーと感じたので、Googleさんが提供している、 「PageSpeed Insights」 という、ツール(サイトの速度改善のための助言がもらえる)を使って、調べてみました。

背景

結果は、こんな感じ…

PageSpeed Insights - モバイル

PageSpeed Insights - パソコン

うーん…ちょっとショック

どうやら、「ブラウザのキャッシュを活用する」を改善するのが一番難易度が低そう(実際に低かったとは言っていない…)なので、これから始めることに。

ブラウザのキャッシュを活用するの画面

AWS S3のキャッシュコントロール(cache control)を一括で書き換えよう

ブラウザ上でも書き換えることは可能なのですが、手間と時間がかかりますし、すでに何十枚もアップロード済み。 なおかつ、これからリソースは増え続けるので、自動化したいものです。

今回は、「AWS SDK for Ruby」を使って、S3内のファイルのキャッシュコントロールを変更することにします。

使用するRubyとaws sdkのバージョンは以下の通り

$ ruby --version
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin14]

$ gem list | grep aws-sdk
aws-sdk (2.3.7, 2.2.36, 2.2.31)
aws-sdk-core (2.3.7, 2.2.36, 2.2.31)
aws-sdk-resources (2.3.7, 2.2.36, 2.2.31)

では、始めましょう

始めに今回使用するソースコードです。

#! /usr/bin/env ruby

require 'aws-sdk'

REGION = "ap-northeast-1"
ACCESS_KEY_ID = ""
SECRET_ACCESS_KEY = ""
BUCKET_NAME = ""
CACHE_CONTROL = "max-age=86400" # one day

Aws.config.update({
  region: REGION,
  credentials: Aws::Credentials.new(ACCESS_KEY_ID, SECRET_ACCESS_KEY)
});

s3 = Aws::S3::Resource.new

# reference an existing bucket by name
bucket = s3.bucket(BUCKET_NAME)

# enumerate every object in a bucket
bucket.objects.each do |object|

  object.copy_from(object, {
    cache_control: CACHE_CONTROL,
    metadata_directive: "REPLACE"
  })

  puts "#{object.key} => cache_control: \"#{CACHE_CONTROL}\""
end

使い方は非常にシンプルです。

  1. ACCESS_KEY_ID, SECRET_ACCESS_KEY, BUCKET_NAMEを入力します
  2. Rubyスクリプトを実行

以上です。

このスクリプトの肝はobject.copy_frommetadata_directiveです。 これを指定しないと、エラーとなってスクリプトが動いてくれません。

補足

今回、この記事で紹介したソースコードはgistに全く同じものを上げています。 MITライセンスを適用しますので、forkなどご自由にどうぞ。

Gist: https://gist.github.com/k4zzk/b219b5e3e51fd5fd1c32a9a4c86929fd

もっと知りたいなと思ったときは!

その他、この記事でわからないことがあったら、teratialというサービスを利用するといいと思います。 勇者が初歩的な質問からマニアックな質問に幅広く答えてくれますよ! 是非、一度使ってはいかがでしょうか?

参考資料