【wordpress(CMS)】パフォーマンスを改善するためにCDNを導入してみた

2021年12月20日

2021年12月20日

こんにちは。Luxyでエンジニアをしている中村です! 先日、別記事でパフォーマンス改善の方法をアップしました。 ここではさらなるパフォーマンス向上をもとめ、CDNを導入してみました。 具体的にはAWSのCloudfrontを使ってCDNを導入します。

現状の確認

まずは現状を確認したいと思います。以前実施したパフォーマンス対策の結果、下記までスコアが改善しました。 (スコアは google pagespeed insightsの値)
【改善前スコア】 モバイル:40.9 PC:91 【改善後スコア】 モバイル:66.1 PC:96.6
ここからはさらなる速度改善を目指し、CDNの導入を行ってみたいと思います。

結論

先に結論から述べておきます。 結果からいうとパフォーマンスは悪くなってしまいました。 それに加えて気になる問題が浮上しています。 上記の問題を3点あげると、 1. CDNでキャッシュした画像ファイルがwebpではなく、pngやjpgになってしまっていて遅い。(.htaccessファイルが動作しないのが原因と思われる。) 2. wordpressテーマに起因する問題(絶対パスによる影響) 3. consoleエラー(CORS policy違反) があります。 これらはブログ最後で詳細に記載します。

まずは手順

作業概要

下記3工程を実施していきます。
  • WordPressでプラグインインストール
  • AWSでIAMユーザの作成
  • WordPressでプラグインの設定

1.プラグインのインストール

インストールしたプラグイン:Amazon AWS CDN  下記URLを参考にインストールしました。(ただし下記URLはAmazon公式のプラグインを入れている) URL:https://blog.mmmcorp.co.jp/blog/2019/11/11/aws-wordpress-plugin-cloudfront-feature/   ただ私の環境(wordpress v5.8.1)ではうまく動作しなかったので、Amazon AWS CDNを利用しました。※できることは同じっぽい。

2.IAMユーザの作成

wordpressのプラグインからAWSを操作するためのユーザをAWSで作成します。(これをIAMユーザと呼ぶ) IAMユーザを作成すると、AccessKeyとSecretKeyが払い出されます。これはwordpressのプラグインに設定するので、忘れないようにメモしましょう。 またIAMユーザ作成の際は下記権限を設定してください。 ・CloudFrontFullAccess ・ACMFullAccess(必要であれば)

3.CloudFrontディストリビューションの作成と有効化

wordpressのプラグインからAWS上にディストリビューションを作成します。 プラグインの画面でIAMユーザのAccessKeyとSecretKeyを入力します。 その他の設定は下記を参考にしてください。 ・Min cacheTime : キャッシュされたコンテンツを最低限保持する時間 ・Max cacheTime : キャッシュされてあコンテンツを保持する最長の時間 ・PriceClass : どこのエッジロケーションでキャッシュするか、とりあえずAsiaが入っているやつでよいと思います。 ・「I would like ~~~」にチェックを入れると、CNAMEを設定できます。この場合別途SSL証明書とDNSの設定が必要になります。(サイトのURLを今と同じにする場合、チェックは不要です。)   全部入力したらCreateDistributionを押下します。   「Activte ~~~cloudfront.net」をクリックすると次の画面になります。 ピンクになっていればCloudFrontが有効になっている状態です。 これで導入は完了です。

詰まったところ

プラグインをインストールし手順にそってCreate Distributionを押下しましたが、いくらボタンをおしてもCDNのディストリビューション作成ができない、という事象が発生しました。調査のためconsoleを確認すると、謎のajaxエラーが発生しており、jsonによるレスポンスが返ってきていませんでした。 いろいろ試したところすべてのプラグインを一時的に無効化したうえで、Create Distributionするとうまく作成できました。 どうやらプラグインの何かが邪魔をして、作成リクエストが送れていなかったようです。作成完了後はプラグインをすべて元に戻しましたが、その後はうまく動作しました。 うまく動作した画像。Networkの情報からCDNからデータを引っ張ってこれているのがわかる。

結果

CDNにしたところ、パフォーマンスが悪化しました。 計測したところ、
【CDN対応前スコア】 モバイル:66.1 PC:96.6【CDN対応後スコア】 モバイル:60.3 PC:95.7
このようになっていることがわかりました。

問題点

CDNでキャッシュした画像ファイルがwebpではなく、pngやjpgになってしまっていて遅い。(.htaccessファイルが動作しないのが原因と思われる。)

パフォーマンスが大きく落ちてしまった影響はこれだと想定されます。 どうやらCDNでキャッシュした時、次世代フォーマットである画像ファイルwebpがキャッシュされるのではなく、大本のpngやjpgがキャッシュされているようです。 結果パフォーマンス改善的には、
CDN + pngやjpg < 次世代フォーマット対応
となっていることがわかりました。 こうなってしまった原因は、xserverとwebpのプラグインにあるのでは、と推測しています。 webpのプラグインでは、元々投稿されているpng、jpgを別フォルダにwebp画像として変換し、配置しています。 つまりフォルダ階層としては下記のようになります。
imgフォルダ ┣━ png,jpgフォルダ ┗━ webpフォルダ (※イメージ図。厳密には違う)
imgファイルが指定されたとき、.htaccessファイルがパスを変えているので、htmlの修正を行わなくてもwebpが読めこめるようになっています。 しかし、CDNのキャッシュは、この.htaccessを無視してpngファイルを見に行っているように見えます。その結果、webpがキャッシュされないという問題が発生しているようです。 実はxsererはnginxとapacheが共存しており、nginxはhtaccessに対応していないから、発生してしまっているのかな?と思いました。 解決方法は、html側のimgパスを.webpに変えることだと思いますが、 さすがに工数が膨大になるし、webpに対応していない端末で見た時に対応ができない(今時そんなデバイスは少ないので影響は小規模だが)ので、この対応はあまりしたくないです。

wordpressテーマに起因する問題(絶対パスによる影響)

wordpressテーマの部品で、html上の画像パスを「絶対パス」で読んでいる箇所がありました。(例: http://大本のドメイン.com/img/image.png のような形式)この結果CDNのキャッシュが効かず、自社サーバーから直接画像を呼び出す動作となってしまっているのでは、とおもいます。 対処方法はwordpressテーマの該当箇所をプログラム的に修正することですが、 ・場所の特定が難しい ・テーマをバージョンアップした際、自分の行った修正は消えてしまう ことから無駄な保守工数がかかってしまうと思いました。

consoleエラー(CORS policy違反)

CDNにしたところconsoleエラーが大量に表示されました。 内容はすべて、「外部フォントの読み込みのCORS policy違反」です。 これはwordpressテーマが、外部フォントを読み込みに行っている場所でエラーが発生しているようです。
例:  http://mplus-webfonts.sourceforge.jp/mplus-1p-regular.ttf
このような記述があると今までは ・自社ドメイン → webフォントドメイン だったので問題なかったが、CDNを導入することで ・CDNサーバー → 自社ドメイン → webフォントドメイン という構造になってしまい、CORS policyエラーが表示されてしまったのだと思われます。
参考:CORSとは https://javascript.keicode.com/newjs/what-is-cors.php
これは 1. フォントデータを自社サーバー側にもってきて配置。 2. wordpressテーマで外部フォント指定している箇所があれば、サーバー内の相対パスに変更する。 で解決するかと思います。 外部フォントを使っていないのであれば無視しても問題ありません。 ただやはりconsoleにエラーが出ているのは気持ち悪いとは思います。   以上、問題に関する考察でした。 CDNは仕組みとして、「世界各地に用意されたCDNサーバーにデータをキャッシュし、誰かがアクセスした際一番近いCDNサーバーを参照する」という仕組みで速度を出しています。 したがって大規模なwebサービスを世界展開する際には有効な選択肢になるかと思いました。 それではまた。