👋

はじめてのCloudflare Images その6、Polishで画像の圧縮による最適化を行う

2023/04/23に公開

この記事では3番目のサービスであるCloudflare Polishを触ります。今までの簡単なまとめですが、Imagesはあらかじめセットしたvariantsに応じて画像を読み込まれたタイミングで動的に変換します。画像のピクセルサイズ変更だけではなく、ぼかしを入れる機能などもあらかじめvariantsを作成しておくことで処理が可能です。variantsとは、画像を変換させるためのルールのようなものです。
Image Resizingでは、variantsを用いずにURLパラメータ、もしくはWorkersからのfetch関数に専用オブジェクトでパラメータを渡すことでより動的に画像の変換を実現します。オーバーレイ、もしくはウォーターマーク機能があり、別の画像を透かしとしてオリジナル画像にかぶせて表示されることも可能です。

Polishは画像のピクセルサイズ変更ではなく、画像の圧縮を行います。Image Resizingではqualityパラメータにより画像の品質を下げることで画像サイズを縮小し転送量を減らす機能が提供されていますが、Polishは対して画像の圧縮を行います。非可逆圧縮が行われるケースがあることに注意してください。

Image Resizingで品質を落とした画像例

Polishで圧縮を行った画像例

Image Resizingの方はかなり品質が落ちていることがわかります。一方Polishの方は圧縮後も綺麗に見えています。
(このサンプル画像はCloudflare の[ドキュメント状の画像]https://developers.cloudflare.com/images/polish/)をそのまま用いましたので、サイズが計測できませんでした。

Polish利用の注意点ですが、Image Resizingと組み合わせて使用を行えないという制限がありまImage Resizingではオリジナル画像に対してサイズ変更を目的とする非可逆圧縮方式による画像変換を実施しますが、その画像を再度Polishに用いることはできません。このため画像のピクセルサイズ変換を行いたい場合、Imagesと組み合わせて利用するのが一般的です。単独で利用した場合ピクセルサイズ変更は行えず、圧縮のみが行われファイルサイズ変更のみが実施されます。圧縮の際の画像品質劣化については後述します。

また、Polishにせよ、その他サービスにせよ動的に変換された画像はキャッシュされるため、そのキャッシュをテスト時は削除する(CDN用語でパージと言います。ロボットが装甲をパージする、と語源は同じです)必要があります。

キャッシュのパージ
こちらのドキュメントにその方法がまとまっています。この手順では最も単純な完全パージを行います。
マネージメントコンソール左ペインからCachingConfigurationをクリックします

"Purge Everything"を押します。

注意点:この作業を行うと、作業中ドメインのすべてのキャッシュが削除されます。キャッシュの削除はオリジンの通信量の増大やパフォーマンスの低下など様々な問題を引き起こしますので、普段お使いの環境で作業をする際には以下のように"Custom Purge"を選んで、URL単位やファイル単位などで削除するようにしてください。

API経由で特定ファイルのパージを行い場合以下のようになります。

curl -X DELETE "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
     -H "X-Auth-Email: {email}" \
     -H "X-Auth-Key: {key}" \
     -H "Content-Type: application/json" \
     --data '{"files":["https://example.com/css/styles.css"]}'

Polishの有効化
PolishはImage Resizingと同じ画面にあります。Proプラン以上が必要です。
左ペインのSpeedOptimizationをクリックします。

圧縮方式をLosslessかLossyから選択します。この設定は以下のような違いがあります。

Lossy:画像品質を劣化させて圧縮を行いますが、影響はPolishにより極小化されます。
非可逆圧縮方式となるため、もともと非可逆圧縮方式のJPEGのみ圧縮を行い、PNG、GIFはメタデータの削除のみです。

Lossless:不要なデータ削除により圧縮を行いますが、画像品質に影響はありません。
可逆圧縮方式となるため、JPEGにはメタデータ削除のみが行われます。(もともとJPEGは非可逆圧縮方式であるため)一方PNG、GIFは可逆圧縮が行われます。

両方のモードで、画像のメタデータは可能な限り削除されます。

次にWebP形式を用いるかの設定を行います。

WebP形式はGoogleにより制定された新しい画像フォーマットで、従来のJPEGやPNGより高い圧縮を一般的に行います。この機能がオンとなっている場合、ブラウザがWebPに対応していればWebP形式に画像を変換して出力します。
注意点ですが、Polishはオリジン画像でWebPをサポートしていません。 オリジン画像がWebP形式であった場合、何も最適化がなされずそのまま出力されます。

また以下のような場合はWebPは出力されずオリジナル画像フォーマットのまま最適化されます。
・ブラウザが対応していない場合(Acceptヘッダにwebpが含まれない場合)
・変換後画質低下が大きい場合、もしくはファイルサイズが増える場合
・Losslessモードのほとんどのケース(上の行と同じ意味ですが、効果が出ずらいため)

それぞれの方式による平均的な圧縮効率は以下のようになっています。

やってみる
まずテストを行う際には上記LosslessやLossy設定、WebPフラグ設定変更を行った後、キャッシュをパージ後数分待ったのちテストを行ってください。設定が正しく反映される過去と同じものがダウンロードされるケースがあります。

では画像がホスティングされているオリジンを用意します。

http://ec2-3-115-22-223.ap-northeast-1.compute.amazonaws.com/icons/apache_pb2.gif

いつもの通りDNS Proxyモードで
DNS設定を行います。

そうすると以下のURLでアクセスが可能となります。

https://imageresize.harunobukameda.labrat.online/icons/apache_pb2.gif

画像がWebP形式で配信されていることがわかります。

JPEGの場合以下です。
オリジナル

http://ec2-3-115-22-223.ap-northeast-1.compute.amazonaws.com/288_shinryoku_sky_6715.jpg

変換後

https://imageresize.harunobukameda.labrat.online/288_shinryoku_sky_6715.jpg

JPEGテストで用いた設定は以下です。

Exif情報を確認できるサイトやツールで確認すると変換後のWebP画像はメタデータ消えていることがわかります。

Discussion