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

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

January 04, 2018

5 min read

mitsuruogMitsuru Ogawa

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

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

はじめに

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

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

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

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

カスタマイズした点

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

環境変数の利用

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

const DEFAULT_DST_BUCKET = process.env.DST_BUCKET;

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

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

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

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を使って設定を渡すことができます。

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 で確認することができる、関数の概要図です。わかりやすい。

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