こんにちは。fotowa開発グループでエンジニアをしている小澤です。 今回は以前にSEO対策の一貫として実施したCDNの導入について話します。
CDNとは
CDN(Content Delivery Network)は、自身のサーバーからコンテンツを直接配信するのではなく、CDNサービスが持つ多数のキャッシュサーバーからコンテンツを配信する仕組みです。導入の主なメリットとして、ページ表示速度の向上やアクセス負荷の分散が期待できます。
CDN導入を決めた背景と目的
昨今Googleはユーザーに良いインターネット体験を提供するためにはコンテンツの品質だけでなく、ページの表示速度も重要であると考えています。 そのため、コンテンツの中身が良くてもページの表示速度が遅ければ、検索順位が低くなる可能性があります。
fotowa(出張撮影サービス)では有難いことに撮影後の評価が平均4.9と満足度の高い口コミをいただいております。ただサービスの性質上、多くの画像を表示する必要があり、それらがページの表示速度が遅くなる原因になっていました。
そこで画像を最適化して容量を減らし、表示速度を上げる施策の実施に至りました。ただしシステム側で何種類もの異なるサイズの画像を作成し、サーバー上に保存するのは避けたかったので、CDNを利用することに決めました。
imgIXにした理由
多数のCDNの中でImgIXにしたのは、多くの便利な機能と導入のしやすさが決め手でした。 他候補だとCloudFrontやFastly、ImageFluxも検討しましたが、料金も考慮した上で総合的に判断して決定しました。なお、ImageFluxも機能は充実してましたが、料金が不明瞭だったため選択肢から外しました。
多くの便利な機能
imgIXは画像URLにパラメータを指定するだけで画像リサイズ、表示品質が調整できるので快適でした。webp変換とウォーターマーク合成機能も画像の最適化に役立ちました。 画像用のCDNということもあり、画像のトリミングや明るさ調整等と他にも多くの機能があります。興味がある方は、imgIXのAPIリファレンスをご覧ください。
導入のしやすさ
基本的にはImgIXの管理画面から画像の取得元(Amazon S3やGoogle Cloud等を選択可能)を指定した後に、アプリケーションにimgIXが提供しているライブラリを導入し、適用対象のコードを置き換えるだけで適用できます。
fotowaはRailsで開発しているため、image_tag
(画像を表示するメソッド)をimgix-railsに定義されているix_image_tag
に変更するだけで概ね対応できました。
このお手軽さは汎用的なCDNであるCloudFront、Fastlyでは難しいと思うので、大きなアドバンテージです。
調査したところ、CloudFrontは画像リサイズのためにLamdaを書く必要があり、Fastlyはimgix-rails
のように専用のヘルパーメソッドを導入できるgemを提供していないため、ドキュメントを読んで全て自前で実装する必要がありました。
料金について
CDNを適用する画像が多いため、適用前と比べて料金が増加することを懸念していました。 適用対象のオリジナルの画像数、転送量、リクエストにかかる料金から、それぞれのCDNで1ヶ月当たりの料金の見積もりを試算したところ、CloudFrontが最も安く、次にFastly、ImgIXという結果になりました。 ただしそれらの料金差が少なかったため、使い勝手が最も良いimgIXに決めました。
苦労したポイント
概ねCDNの適用は順調でしたが、いくつか苦労したところもあったので参考までに紹介いたします。
CDNを適用する画像の多さ
fotowaは写真がメインのサービスなので、フォトグラファーのポートフォリオや口コミの画像など、多くの画像を表示しています。ユーザーは画像を見て依頼するフォトグラファーを選ぶため、画像の見栄えはとても重要です。そのため、一律で品質を決めることはできず、適用箇所ごとに画像の表示品質と軽さのバランスを取るのが大変でした。 様々な品質でCDNを適用した画像をデザイナーに共有し、こまめに相談して画像のサイズと品質を決めました。ただし適用を進めていく中で、対象の画像が合計で約1000箇所まで増加し、これら1つ1つに対して最適なパラメータを決めるのは大変なので、大まかにグルーピングして段階的に適用していきました。
app/assets
ディレクトリ以下の画像へのCDN適用
Railsではapp/assets
以下に、アプリケーション自身が保有するファイルを置きます(これらのファイルはプリコンパイルされて通常public/assets
以下に出力されます)。
以前のfotowaでは開発・本番環境共に、環境ごとに複数存在するwebサーバーからassetsファイルを配信していました。そこでまずS3にassetsファイルを置くように変更し、imgIXとの紐付けを簡単にできるようにしました。特にローカル環境でもimgIXを使用する場合は、お手軽に実現できるのでお勧めです。
なお、S3へのassetsファイルのアップロードには、asset syncを使用しました。
CloudFrontとの併用
assets以下のCSSやJS等の静的ファイルにもCDNを適用して、更に表示速度を高速化するためにCloudFrontを導入しました。通常はasset_host
にCloudFrontのドメインを指定するだけで対応できますが、全てのassetsファイルが対象になるのでimgIXを適用した画像のパスにもCloudFrontのドメインが混在してしまうという問題がありました。ただしこちらはasset_path
の代わりに、asset_hostの値を無視するcompute_asset_path
を使うことで解決できました。
def assets_ix_image_tag(path, url_params: {}, srcset_options: {}, tag_options: {}) ix_image_tag( domain, compute_asset_path(path), url_params: url_params, srcset_options: srcset_options, tag_options: tag_options, ) end
まとめ
約1000箇所の画像サイズを削減(大きいサイズの画像で7割近く減少)したことで、体感できるレベルでページの表示が早くなりました。また、任意のサイズでのサムネイル作成が容易になり、デザイナーが新しい画像の最適化まで対応できるようになりました。 そしてCDNの適用後、本来の目的である検索順位の向上についてマーケティングチームからポジティブなフィードバックをいただきました。
ピクスタでは、自発的に動いてサービスを成長させたいエンジニアを絶賛募集中です!