imgixでお手軽に画像配信を最適化

読者のみなさま、ご無沙汰しております。管理人のたかきです。

最近、新しいウェブアプリケーションを開発しており、今のところ約半年を費やしてアカウント管理機能を作っております。

その中で、の画像のような感じでユーザーのプロフィール画像(アイコン)を設定する機能を作っていたのですが、画像のアップロードを受けとり、ユーザーの指定に従って正方形に切り取ってGoogle Cloud Storageへアップロードするまでの処理はできたのですが、問題は画像の配信です。

Exifのオリエンテーション補正や、Reactのクロップツールの導入、Node.jsでの画像クロップなど、なかなか大変でした…

マスター画像は400x400pxでGCS上に保存してあり、独自ドメインでCloudFlareのCDNを経由するよう設定していたため、生のURLをクライアントからリクエストされた場合でもキャッシュヒットをすることは可能なのですが、いかんせん参照する際に400pxの画像をいちいちリクエストするのは無駄がありすぎます…

たとえばちょっとした右上のアカウントアイコンは50pxもあれば十分ですから、400pxの画像をリクエストするのは時間もかかりますし、ユーザーのデバイスの通信量も消費してしまいます。

そこで、画像配信に特化したCDNを導入してみましたので、今回はそのご紹介です。

最も理想的にはCloudFlareに画像のリサイズ機能(たとえば?w=40というクエリをつけたら40pxにリサイズされたものが得られる等)があればよいのですが、あくまでCloudFlareはただのCDNですのでそういった機能はありません。

(2020/04/19追記)
大変失礼いたしました。きちんと調べたところCloudFlareにもImage Resizing機能が提供されておりました。

なんとこちら、CloudFlareを経由するURLが

https://cdn.example.com/image.jpg

だった場合、

https://cdn.example.com/cdn-cgi/image/width=200/image.jpg

などとするだけで利用できるようです!素晴らしくお手軽!

と思いきや、こちらのサービスはCloudFlareのBusinessまたはEnterpriseの上位プランで契約している方のみに提供されている機能のようです。というわけで私は実験してみることができませんでした…

imgixという画像配信最適化サービス

そこで仕方なく、画像をリサイズして配信してくれるCDNについて調べてみたところ、imgixというサービスが良さげだったので利用してみることにしました。

こちらの画像はimgixのトップページに掲載されていたものですが、ご覧のように適当にクエリストリングをつけるだけで画像のリサイズに限らず、様々な画像処理を行って出力してくれるようです。そして何より嬉しいのはimgixの方で自動的にCDNを構成してくれるので配信の最適化など何も考えなくて良いということ!

国内では、日本経済新聞社や一休.comやQiitaなどが同社のサービスを利用しているようです。

料金は…?

2020年4月16日現在の情報です。ご利用にあたっては必ずご自身で最新の情報をご確認ください。

料金体系はとてもシンプルで、アクセスされるマスター画像の枚数とCDNの転送量で決まるようです。

マスター画像は1000枚ごとに月3ドル、CDNの転送量は1GBごとに8セントということですが、これを超えなければ無料と言うことでしょうか?来月請求書がきたら追記します。

(2020/04/19追記)管理画面の請求明細を確認したところ、マスター画像の枚数、転送量ともに最低課金料に届かない場合でも、最低利用料金として3.08ドル/月の請求が発生するようでした。しかしサインアップ後10ドルの無料クレジットが適用されるため、3ヶ月間は費用負担無しで利用できそうです。
その後はもちろん支払いをしないとサービスの提供が停止するようになっています。

競合サービスのGumletは毎月1GBまでの転送量はずっと無料で利用できるようですので、趣味の開発程度であればこちらのほうが良いかもしれません。

Gumletのドキュメントを少し読んでみましたが、画像のリサイズ程度であればimgixとほぼ同様に利用可能ですし、小規模ユースではimgixよりコストが抑えられそうです。
ただ、運営会社が「About us」ページを読んでもいまいちよくわからず、また日本での採用事例もほとんどありませんので、安定性はわかりません…

imgixとGCSの接続

スクショなどを取り忘れこちらに載せられず申し訳ないのですが、imgixの利用にはまずオリジナルの画像ソースにアクセスするための設定が必要です。

imgixの管理画面に初回ログインした際に、画像の保存場所を尋ねられ(Amazon S3などもありました)、GCSを選択したところ何やら接続情報のようなものを求められました。

GCSのIAMについてまだ良くわからないのですが、GCSの設定項目に「サービスアカウントのアクセスキー」というのがあり、こちらで作成したキーペアを入力することで無事imgixとGCSとの接続設定が完了しました。

なにやらよくわかりませんが、おそらくこのキーはGCSバケットごとに発行できるアプリパスワードのようなもので、外部サービスとの相互運用性のためにリソースの一部に対するアクセス権を与えるために存在しているようです。

とはいえ、imgixの画像ソースには単純なHTTP(S)エンドポイントも設定できるようです。あくまでクラウド上のストレージサービスでなくとも、皆様がすでに運用中のWebサーバーからシームレスに移行することができます。

WordPressのプラグインも用意されているようですから、おそらくそれを使えばWordPressの画像配信をimgix経由にすることでサイトの高速化が図れそうです。画像を多用するメディアなどを運用されている場合は単純なCDNの導入よりも効果があるかもしれませんね。

画像へのアクセス

imgixに画像のソースを設定する際、サブドメインを決めることができるようになっています。そこで任意に設定できるサブドメインですが、もしyour-contentと設定した場合、あなたの画像は

https://your-content.imgix.net/filename

というアドレスでアクセスできます。またURL末尾に?w=200などとクエリをつけると画像のリサイズなど色々な画像処理を行うことができます。

1回目のリクエストは一瞬待たされますが、その後はしばらくimgixが構成してくれているCDNにキャッシュされるので高速で配信されます。HTTPのレスポンスヘッダをなんとなく見てみると、キャッシュサーバーのホスト名でしょうか?

x-served-by: cache-lax8634-LAX, cache-hnd18737-HND

というヘッダがついていました。LAXやHNDは3レターコード(空港の識別コード)でしょうから、ロサンゼルスと東京にあるキャッシュサーバーでヒットしましたという意味でしょうか?

なかなか遊び心があっていいですね!

そんな感じで…

無事、画像の配信については現代の偉大なテクノロジーと少しのお金の力により課題をクリアすることができました。

とはいえ、私のアカウント管理システムはまだまだ完成まで課題が山積みです。とても具体的な話になるのですが、実はここ3日間はORマッパーが言うことを聞かず(Model instanceの一部データを更新してもUpdateではなくInsertしてしまう)、その解決にかなりの時間を使ってしまいました。結果的にModelを二重にインスタンス化しているというわけのわからない私のミスだったのですが、とても骨が折れました…

そんなこんなで半年かけても全く完成の兆しが見えない私のシステムです(私は自分でサグラダ・ファミリアと呼んでいます)が、最近は新型コロナウイルスの伝染が深刻化しほとんど外出を控えていますので、以前より多くの時間を開発に充てることができています。

「コロナ疲れ」という言葉も耳にしますが、正直に申し上げると私はこんなに長い時間プログラミングばかりすることができて大変幸せに感じています。将来はやっぱりエンジニアをするのがQOLを上げるには一番かな、なんて思っている今日このごろです。

それでは、今回はこのへんで。長くて少し専門的な記事でしたがお読みいただきありがとうございました。内容でご不明な点などありましたらお気軽にコメントください!