dev.toに学ぶ画像最適化のヒント #Cloudinary

爆速サイト「dev.to」は画像CDNのCloudinaryをどのように活用して画像配信を最適化しているのか解説します。
2020.05.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

表示速度が爆速で話題になったソフトウェア開発者向けのコミュニティサイト「dev.to」は画像の高速配信にCloudinaryを利用しています。

Images are automatically optimized for compression and served from the most efficient format depending on the browser (webp for Chrome, jpeg for Safari, etc.). This is a service provided by Cloudinary. Cloudinary also fully leverages HTTP2 where possible so we do not have to think about it.


画像は自動的に圧縮に最適化され、ブラウザ(Chromeではwebp、Safariではjpegなど)に応じて最も効率的な形式で提供されます。これはCloudinaryが提供するサービスです。また、Cloudinaryは可能な限りHTTP2をフルに活用しているので、何も考えなくても大丈夫です。 ※DeepLの日本語訳

Making dev.to Incredibly fast - DEV Community ?‍??‍?

本ブログでは、Cloudinary

  • 画像の圧縮
  • ブラウザごとに効率的な画像形式に変換
  • HTTP/2通信

についてdev.toを例に紹介します。

Cloudinary とは

まずはCloudinaryについて簡単に紹介します。

Cloudinaryは画像を最適化するサービスです。SaaSのため、画像処理の知識や画像変換システムの開発・運用は不要です。

URIのパス部を利用し、動的に画像処理します。

例えば、dev.toには次のような画像URIです(一部加工)。

https://res.cloudinary.com
  /practicaldev ← クラウド名
  /image ←リソースタイプ
  /fetch ← タイプ
  /s--RFBNolAd-- ← バージョン
  /f_auto,h_180,q_auto,w_180 ← 画像変換処理パラメータ
  /https://XXX.s3.amazonaws.com/test.png ← 対象リソース

「タイプ」fetchとなってとなっており、「対象リソース」はS3のURIになっています。 これは、オリジンのS3にオンデマンドでフェッチし、Cloudinary側にキャッシュすることを意味します。

Cloudinaryからクライアントへのレスポンス時に、画像変換処理パラメータに合わせて画像を処理します。

画像変換処理のパラメータの意味を解説します。

パラメータ 意味
f_auto 画像形式(JPEG,WebPなど)を最適化
q_auto 画質を最適化
h_180 縦幅を180pxに変換
w_180 横幅を180pxに変換

結果的に、S3オリジンでは820 KBのPNG画像がわずか6 KBのWebP画像に生まれ変わっています。

以下では Cloudinary の

  • 画像の圧縮
  • ブラウザごとに効率的な画像形式に変換
  • HTTP/2通信

についてdev.toを例に紹介します。

画像の圧縮

テキスト系アセットはgzipなどで圧縮されることが多いものの、メディア系アセットが圧縮されることは稀です。ウェブサイトのペイロードの大部分を画像が占めるにも関わらずです。

Cloudinary ではq_オプションパラメーターを渡すと画像を最適化できます。

dev.to はおまかせ(q_auto)モードになっており、人間では違いがわかりにくい範囲で画像を最適化しています。

ブラウザごとに効率的な画像形式に変換

JPEGやGIFといった前世紀から存在する画像形式が現在も利用されている一方で、WebP、JPEG 2000、JPEG XRのようなより効率的な画像形式も普及しています。

Cloudinary ではf_オプションパラメーターを渡すと画像フォーマットを最適化できます。

dev.to はおまかせ(f_auto)モードになっており、ChromeにはWebP、Safariには JPEG 2000というように、ブラウザーに最適なフォーマットに最適化しています。

HTTP/2通信

Cloudinaryは HTTP/2 で画像配信しています。

ChromeのDeveloper ToolsでCloudinaryとの通信を確認します。

  • Protocol : h2
  • Connection ID : 4605501のみ

から、CloudinaryにHTTP/2接続し、1 コネクションを使いまわして、大量の画像を同時に取得していることがわかります。

ドメインあたりの同時接続数(6リクエスト)が存在するために、ドメインシャーディングが行われていたHTTP/1.1時代よりも効率的に通信しています。

おまけ:CloudinaryのCDN

効率よくコンテンツ配信にはCDNの利用も不可欠です。

画像管理、画像変換、CDN配信までを含めたワンストップ・ソリューションのCloudinaryはAkamai,Fastly、CloudFrontといった複数のCDNを利用しています。 さらには、中国でも利用可能です

digやレスポンスヘッダーの Server-Timing から配信CDNを確認できます。

筆者の環境では Fastly から配信されていました。

HEAD結果

$ curl -I https://res.cloudinary.com/practicaldev/image/fetch/c_scale,fl_progressive,q_auto,w_180/f_auto/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/devlogo-pwa-512.png
HTTP/1.1 200 OK
...
Server-Timing: fastly;dur=0;total=1;start=2020-05-13T16:20:17.506Z;desc=hit,rtt;dur=18  ← Fastly
Server: Cloudinary
...

dig結果

$ dig res.cloudinary.com

; <<>> DiG 9.10.6 <<>> res.cloudinary.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38838
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;res.cloudinary.com.		IN	A

;; ANSWER SECTION:
res.cloudinary.com.	156	IN	CNAME	cloudinary.map.fastly.net.
cloudinary.map.fastly.net. 12	IN	A	151.101.113.137
...

最後に

爆速サイト「dev.to」を例に画像CDNのCloudinaryを使った画像の最適化について紹介しました。

画像最適化ソリューションに興味のある方は、クラスメソッドまでお気軽にご相談ください。

参考