AWS Lambdaを使ってS3にアップロードしたイメージを最適化する
2018-01-05

AWS Lambdaを使ってS3にアップロードしたイメージを最適化する

あけましておめでとうございます。

PageSpeed Insightsを使ってこのブログを計測したところ、画像の最適化とキャッシュを提案されたので、年末年始はAWS Lambdaを使って画像の最適化を試していました。

はじめに

やりたかったことは、ブログで使う画像を最適化してサイズを小さくすることです。

ブログの画像ファイルは全てS3から配信しているので、特定のS3バケットに画像がアップロードして、それをLambda関数で最適化して他のバケットにアップロードすると言った、よくあるユースケースを実現してみました。

出来上がったものは、下のリポジトリにおいてあります。

正直なところ下のAWS公式チュートリアルを少し改造しただけなので、これをそのまま使うよりはチュートリアルで自分で試して見た方がいいと思います。

カスタマイズした点

カスタマイズした点について少し触れておきます。

環境変数の利用

Lambda関数の設定画面から環境変数を設定することができたので、一部の変数を実行時に渡すようにしました。
Lambda関数の中ではprocess.envにアタッチされるので、次のように利用できます。

1
const DEFAULT_DST_BUCKET = process.env.DST_BUCKET;

画像へのキャッシュの指定方法

S3にアップロードされた画像にキャッシュを指定するには、S3オブジェクトのメタデータを使ってHTTPヘッダーを追加します。
AWS-SDKのS3.putObjectを見ると、CacheControlExpiresを使うことで、キャッシュ関連の設定を渡すことができます。

次のように設定してみました。

1
2
3
4
5
6
7
8
s3.putObject({
Bucket: YOUR_TARGET_BUCKET_NAME,
Key: "image.png",
Body: data, // image data
ContentType: "image/png",
CacheControl: "max-age=86400", // 86400s => 1day
Expires: new Date(new Date().getTime() + (86400 * 1000)) // 現在日時より1日後
});

S3バケットのメタデータを確認すると、次のように表示されます。(上の値と違いますが。。。)

画像をアップロード時に「public」設定にする

これもS3.putObjectACLを使って設定を渡すことができます。

1
2
3
4
5
6
7
8
9
s3.putObject({
Bucket: YOUR_TARGET_BUCKET_NAME,
Key: "image.png",
Body: data, // image data
ContentType: "image/png",
CacheControl: "max-age=86400", // 86400s => 1day
Expires: new Date(new Date().getTime() + (86400 * 1000)), // 現在日時より1日後
ACL: "public-read"
});

次の値が設定できるようです。

  • “private”
  • “public-read”
  • “public-read-write”
  • “authenticated-read”
  • “aws-exec-read”
  • “bucket-owner-read”
  • “bucket-owner-full-control”

結果

結果どれくらいサイズが小さくなったかというと。。。

22.3MB => 16.2MB

うん、微妙。ちょっと減りました。
画像最適化をもう少し強くするともう少しサイズは減るかもしれません。

さいごに

Lambdaの動作確認にちょうどいい感じだったので、正月休みに画像の最適化用のLambda関数を作ってみた話でした。
出始めの頃と比べるとGUIでできる範囲が増えたので楽でした。

こちらはGUIのDesignerで確認することができる、関数の概要図です。わかりやすい。

もう少しいいものがあるので、自分で試さない場合はこのあたりもチェックしてみてください。