バックエンドエンジニアとLighthouse
はじめに
仕事で作ったAWS環境をLighthouseにかけられる刑に処されました。
前提
- サイトはNuxt.jsで構築
- 管理画面はWordPressを使用し、NuxtからはWP REST APIを使用
- AWSについては下記の構成
- EC2(t3.small * 1台)
- ALB
- Route53
- S3
- CloudFront
バックエンドエンジニアがLighthouseで考えること
バックエンドエンジニアとしてやった対策をまとめてみました。
Performance
Enable text compression
テキスト圧縮の有効化
リクエストヘッダにAccept-Encoding
が含まれている場合、テキスト形式のデータを圧縮してデータ通信量を削減することができます。
Apacheで設定する場合
mod_deflateが導入されているのを確認した上で、下記のような設定を記述します。
<IfModule mod_deflate.c> SetOutputFilter DEFLATE AddOutputFilterByType DEFLATE text/html text/plain </IfModule>
CloudFrontで設定する場合
今回の場合ではS3など、CloudFrontをかまして配信されているコンテンツの場合は、CloudFront側でテキスト圧縮が可能です。コンソールから2, 3ポチで設定できます。
Uses efficient cache policy on static assets
静的なアセットと効率的なキャッシュ ポリシーの配信
端的に言ってしまうとcache-controlの設定です。Apacheなどであれば設定ファイルでどうとでもなりますが、S3で配信しているファイルのキャッシュ設定はやや面倒です。
Apacheの場合
<ifModule mod_expires.c> ExpiresActive On ExpiresByType image/png "access plus 1 month" </ifModule>
mod_expiresを使用して設定します。
直接cache-controlヘッダを追加することでも対応できます。
参考:Apache httpd の mod_expires でキャッシュ有効期限を設定しよう | WEB ARCH LABO
S3の場合
S3オブジェクトはメタデータを設定することで、アクセスした際のヘッダを指定することができます。
ただ、上記のようにファイルひとつずつキャッシュをさせることはできても、Apacheのように特定のタイプのファイルをまとめて設定することができません。S3を使う場合はだいたい結構なファイル数を扱うことが多いと思われるので、ひとつひとつメタデータを設定するのは現実的な運用ではない…。
このあたりはどういう運用をするかにもよりますが、アップロード時に処理をかまし、S3にアップロードされた時点で適切なメタデータが設定されている状態にするのが正攻法かと思います。すでにアップロードされている多数のファイルのメタデータを変更するという場合は、aws s3 sync
コマンドをうまく使うといいかもしれません。
Keep Server Response Times Low
サーバーのレスポンスタイムを低く保つ
ここがサーバサイドエンジニアの腕の見せどころでしょう。ですよね。ボトルネックを見極めたうえで、さまざまな手段を用いて迅速にレスポンスを返してやることが求められます。
打てる施策も幅広いので、ここでは僕がよくやることリストをいくつか紹介してお茶を濁しておきましょう。
サーバサイドキャッシュ
ささっとできて爆発的な効果をもたらしやすいと話題のキャッシュくんです。キャッシュ施策をまだ打っていないのであれば、真っ先にやってみるといいです。
簡単なのはファイルキャッシュですが、しっかりやりたいならmemcachedやRedisを検討します。今回はWP REST APIの呼び出しがボトルネックになっていたため、WP REST Cacheというプラグインを使用してがっつりキャッシュをかけました。
一点注意として、何も考えずにキャッシュを導入するのはリスクである、ということは肝に命じておきましょう。
キャッシュを消すタイミングや、不適切なユーザーにキャッシュが使われることはないかといった運用上の懸念は意識しておく必要がありますし、知らず知らずのうちに使われていたキャッシュのせいで不具合の原因特定に時間がかかってしまう、というのもよくある話です。
DBクエリチューニング
DBは総じてボトルネックになりがちです。ボトルネック特定のための計測についてもDB周りを狙い撃ちしてみるといいでしょう。
スロークエリログやフレームワークのデバッグツールを活用しながら、適宜インデックスを張っていきます。
Apacheチューニング
Apacheでは同時にリクエストを捌くプロセス数を設定で変更することができます。適正値はサイトの性質やアクセス数により大きく変わるため、実際に運用しながらチューニングしたり、事前に負荷テストをしておくのがいいかもしれません。
また、場合によってはApacheを使用せず、同時接続に強いNginxを採用するという選択肢を取ってもいいでしょう。
Avoid multiple page redirects
複数のページ リダイレクトの回避
世の中は様々なリダイレクトに溢れています。リダイレクトはたいていの場合過去の業に縛られがちなので、業の深いサイトはおびただしいリダイレクトが発生し、管理しきれなくなったりします。気を付けましょう。
Best Practices
Uses HTTPS
今どきフォームや個人情報を扱っていなくても、SSL化ぐらいはしておくようにしたいですね。AWSを使っているならALBで証明書を登録しておくと、Webサーバ側でSSL化のことを気にしなくて良くなるので幸せです。
Uses HTTP/2 its own resources
上述のALBを使用しているなら、HTTP/2対応もとってもチョロいです。ALBの設定で項目が見つけられるはずなので確認してみましょう。また、CloudFrontを噛ませている場合はそちらで対応することも可能です。
ただ、ALBで対応する場合はEC2側の設定により、Safariでエラーが発生してしまうことがあります。EC2でAmazon Linux2を使用したときに発生するようなので、下記記事を参考にしてください。
参考: AmazonLinux2のhttpdをALB経由で公開するWeb環境で発生していた、SafariのHTTPS接続エラーを改善してみた | DevelopersIO
もちろんwebサーバ側でHTTP/2対応をすることもできます。
SEO
Page has successful HTTP status code
基本的なことですが、HTTPステータスコードは正しく使うようにしましょう。
おわりに
Lighthouseの言いなりになるのがよいというわけではありませんが、バックエンドエンジニアとしてもサイト高速化といった対応の参考になるところが多く、自分の作ったサイトで一度試してみるのもいいのではないかと思います。