FANプログラミングWordPressFramework7Appleお問い合わせホームプログラミングAWSサイト爆速化!?PHPとCloudForontで画像変換キャッシュサーバーを構築する方法2019年11月4日SHAREツイートシェアはてブLINE「Webサイトやアプリに提供する画像って必要最低限のサイズでいいけどそういうこと出来ないかな?」こんにちは、タカフです。Webサイトやアプリや作っていると、そこで表示している画像サイズって気になりますよね。画像サイズが重ければそれだけで画面表示まで時間がかかり、Webサイトならページ表示速度という面でSEOにも響いてきます。アプリに必要な画像サイズというのはその端末サイズでキレイに見れる分だけのサイズであればいいのです。実際アプリに必要な画像はretina対応を考慮してもせいぜい幅600px・高さ400pxの画像さえあれば良いというわけです。いう時に便利なサービスがあります。アプリ側から画像サイズをパラメータとしてURLで指定するとそのサイズで画像変換してくれるサービスです。有名どころだとImgixとかですが、日本製だとさくらサーバーの会社が提供しているImageFluxです。gumletというのもあります。これらのサービスではhttps://www.example.com/img/food.jpg?width=640というようなGETパラメータで画像サイズを指定すると、その画像サイズに変換して且つそのサービス側でキャッシュしてくれて、その後はそのURLなら高速で画像を表示出来るというものです。今回は、そもそもシステム的に使えないとか、小規模だけどアプリやWebサイトを高速化させたい、という時に、このサービスを自前で構築する方法となっています。PHPとCloudFrontを使って自前でこれを構築出来ます。システム概要システム概要図としては以下の通りになります。アプリから必要なサイズで画像リクエストをして、CloudFrontを経由してオリジンサーバーで画像変換をしてリサイズした画像を返すというものです。場合によってはロードバランサーがはさむこともあるでしょうし、また、オリジンサーバーにはAWS以外のサーバーでも指定することが可能です。PHP画像変換処理の実装それではPHPによる画像変換処理を実装していきましょう。今回のシステムは、特定パラメータがついたURLの場合に限り.htaccessでRewriteRuleしてPHP処理をする流れとなっています。画像変換処理ライブラリのインストール.htaccessでRewriteRuleの処理PHPで画像リサイズと画像出力です。順を追って説明します。画像変換処理ライブラリのインストール画像変換処理にはgumletのphp-image-resizeというライブラリを使用します。https://packagist.org/packages/gumlet/php-image-resizeこれを提供しているgumletは上記でも説明した画像変換キャッシュサービスを提供している会社ですが、なんとその処理をライブラリとしてcomposerで提供しているのです。同じ目的で作られたライブラリなのが安心できますよね。CDN.画像をトリミング、サイズ変更、サーバーに保存したくない場合、Gumlet.comは無料のサービスであり、リアルタイムで画像を処理し、CDNを通じて世界中で提供できます。画像変換処理ライブラリは無料で提供することで認知度を広めてここの有料プランを使ってもらうというビジネスモデルなんでしょう。それではcomposerを使ってインストールします。gumlet/php-image-resizeこれだけで画像変換処理が使えるようになりました。画像リクエストがあった時に特定パラメータがついていた場合はPHPを動作させるようにします。以下の.htaccessをオリジンサーバーの画像変換したいディレクトリに設置します。[QSA,L]</IfModule>これにより、少しでもサーバー負荷を上げない為に特定パラメータの時だけ画像変換処理のPHPを動かすようにします。PHPで画像リサイズと画像出力.htaccessと同ディレクトリに以下のPHPを設置します。composerのautoload.phpのパスは適宜変更してください。readfile($image_path);}GETパラメータの値を取得して、その値に従った画像に変換してoutputメソッドで画像としてレスポンス出すようにしてます。キャッシュ時間もここで設定しています。サンプルコードは100日としていますが、システムに応じて任意の値を設定すると良いです。何かしらの例外が発生した時は、元の画像をフェイルセーフとして元画像をそのまま出力する処理にしています。今回のシステムを構築するのに大切なのはそのキャッシュ設定です(Behavior設定)。以下のようなキャッシュ設定にしています。TTLを1年にすることで、あとはキャッシュ時間をオリジンサーバー側で決めるようにしています。$expire_seconds);が実際のキャッシュ時間となるわけですね。この方が柔軟性のあるキャッシュ時間に出来ます。実装結果それでは実際にどのような挙動になるか見ていきましょう。4MBのファイルをサーバーに置いてみて、まずは普通にCloudFront経由でアクセスしてみます。https://xxxxxxxxxxx.cloudfront.net/img/food.jpgはい、3.9MBのファイル容量で、333msもかかってますね。こんな画像がWebサイトに配置されていたら最悪ですね。次にパラメータ付きで幅640でリクエストしてみます。https://xxxxxxxxxxx.cloudfront.net/img/food.jpg?w=6406.67secこそかかってますが、ファイル容量は38KBにも減らすことが出来ました。時間がかかっているのは、このテスト用に立てたサーバーが貧弱だったのと元画像が大きすぎるせいですね。実運用ではアップロード時にも元画像をいくらかリサイズするといいですね。再度同じURLでリクエストをしてみます。https://xxxxxxxxxxx.cloudfront.net/img/food.jpg?w=640今度はキャッシュが効いているので、38KBのファイル容量でかつ18msecにまで短縮出来ました。18msで画像を表示出来たら最高なえくすぺりえんすをユーザーに提供出来ていると言えますね。気をつけるべき事これを実際の稼働で利用するには気をつけるべき事があります。それなりのメモリを積んだサーバーと、いたずら対策が必要です。画像変換にはCPUとメモリーを結構食うので、強力なサーバーでしかやらないとか、もしくはこれ専用として別サーバーを用意するとかした方がいいです。不本意のパラメータでたくさんリクエストを受け付けてその全てを画像変換していると、とてつもないサーバーリソースが必要で最悪サーバーが落ちたりするので、そのようないたずらの対策が必要です。許可された画像サイズだけを画像変換する等の処理を入れておく必要があります。まとめこのスマホ時代かつ格安SIM時代に、通信料のかかるWebサイトやアプリなんてユーザーに受け入れられません。このような工夫を入れることで端末側の通信料は軽くしたり、アプリ表示を高速化することが出来ます。ここまで書いといてなんですが、PHPで画像変換処理は結構サーバーに負荷かかるので、出来ることならAWSのCloudFrontとlambda@edgeを使ってサーバーレスでこの処理をやった方がいいです。その記事はまた別で書こうと思いますが、ただその手法は若干とっつきにくいのでとりあえずお手軽に構築するなら今回のPHP+CloudFrontでの方法でも十分使えると思います。以上、カフーブログの提供でお送りしました。【簡単】DockerでFramework7の開発・ビルド環境を構築するこの記事を書いた人タカフWebエンジニア・Surface専門家Webのフロントエンド・バックエンド・インフラ(AWS)をワンストップで開発出来る事を強みとしているWebエンジニアです。ブログではWeb系プログラミングTips・オススメPC・ガジェットを中心に情報発信しています。株式会社カフーの社長さん。WordPressプラグインの「Crudiator」を開発。コメントをキャンセルメールアドレスが公開されることはありません。@kahoo365Webのフロントエンド・バックエンド・インフラ(AWS)をワンストップで開発出来る事を強みとしているWebエンジニアです。ブログではWeb系プログラミングTips・オススメPC・ガジェットを中心に情報発信しています。株式会社カフーの社長さん。WordPressプラグインの「Crudiator」を開発。執筆書籍Surfaceの使い方を詳しく解説したSurface専用解説本を出版しました!タカフ@WebエンジニアWeb系プログラミングTips・オススメPC・プログラミングスクールを中心に情報発信しています。PCの中でもノートPCが好きで、本当の買うべきノートPCに絞って紹介することが多いです。ITエンジニア歴はいつのまにか15年程。システム開発・Web運営にいそしむ日々。株式会社カフーの社長さん。WordPressのプラグイン開発もしています。Search人気記事1【レビュー】半年使ってわかった。27インチ4Kの最強モニターな件。