Nuxt3×ApacheでLighthouseのPerformance対策

掲載日

はじめに

Googleの調査によると、ページの表示速度が遅ければ遅いほどユーザーの直帰率に影響することがわかっています。
そんなページの表示速度をチェックするためのツールとして「Lighthouse」というものがあり、多くの人が高いスコアを目指していろんな対策を実施しています。

今回は自分のCMSでページスピードの高スコアを出すために行ったことを紹介します。
(基本的にはLighthouseでページを分析→赤い警告がでている項目を対策という手順で修正しています。)

lighthouseで満点を取得した時のスクリーンショット

Nuxt3で行った対策

このCMSはフロントをNuxt3、バックエンドをGolangで書いています。
ユーザーに見てもらう側の画面は基本的にSSR、もしくはISRを使っているのであまりバックエンドは関係ないので割愛。(それに、Golangは何といっても早さが売りなのでSQLチューニングくらいしか早くするために出来ることはないような気がします。)

NuxtImageの導入

imgタグの最適化を行ってくれるモジュールです。
指定したwidth, heightに合わせて自動的にリサイズと圧縮を行うことで、スクリーンショットなどを掲載する際に都度画面サイズに合わせてリサイズしたり、squoosh等を使って画像の圧縮をする必要がなくなります。

こちらの手順に沿って導入し、imgタグを記述している箇所をNuxtImageコンポーネントに書き換えるだけでOKです。

大変ありがたいのが、Nuxt3のディレクトリ構成に入っていない画像でも最適化してくれるところ。
自分のCMSは画像のアップロード処理自体はGolangでやっているので、アップロードしたファイルもそっちで管理しています。(ポートフォワーディングで /upload ディレクトリ配下にアクセスして呼び出しできるようにしています。)

これも、以下のような設定をnuxt.config.tsに入れて呼び出せばちゃんと最適化してくれます。

    image: {
        domains: [
            [任意のドメイン名(ex: example.com)],
        ],
        alias: {
            uploader: [任意のURL(ex: https://example.com/uploader)],
        },
    },
<NuxtImg
 :src="'/uploader' + [画像パス]"
 />

Tailwind CSSの導入

Nuxt3の初期化の際に聞かれる項目でもありますが、cssのフレームワークのTailwind CSSを導入しています。
各要素に定められたclass名を追加することで対応するcssが反映されます。
(class="flex"とすると、display:flexがあたるといった具合)

自分は最初、Tailwind CSSは「あらかじめクラス名とそれに対応するcssを読み込んでるだけでは?最初に大量のcssを読み込むことになるから良くないのでは?」と誤解していたのですが、なんと「ページ内で使用されてるクラス名のスタイルだけを読み込む」ことが出来る優れものです。
クラス名を大量に並べることに対するアレルギー反応が最初はありましたが、上記メリットの前では完治します。
これによって、Lighthouseの「使用していないcssが読み込まれてるよ!」という項目も簡単に解消できます。

compressPublicAssetsをtrueにする

nuxt.config.tsに以下を追加します。

    nitro: {
        compressPublicAssets: true,
    },

この設定を追加することで、ビルド時にassets配下、pubilc配下のファイルを圧縮配信してくれるようになります。ただ、これはページ自体の圧縮配信はできない?ようなので後述のApacheの対策も入れました。

Apacheで行った対策

このCMSはApache2.4を使って配信しています。
Apache側の設定でもかなりパフォーマンスを上げられるので以下のような設定を行いました。

HTTP2.0

HTTP2.0という仕組みでデータの通信を行います。
HTTP2.0は、詳しい仕組みは上記リンクの通りですが、ざっくり「これまでは1個ずつデータをやり取りしていたのを、まとめて一気に送受信できるようにした」という感じだと思います。
(ネットワークに関してはアバウトな理解しかないので、厳密には多分違う。)

通信の仕組みを変えるというとなんともややこしそうですが、実際にはssl.confに以下を追記するだけでOKです。

Protocols h2 http/1.1

なお、まとめて送受信するためかサーバーへの負荷は大きくなるようです。
個人サイトでは気軽に入れられますが、業務で作るようなものではサーバーへの負荷などを考慮して導入が必要だと思います。

圧縮配信

nuxtの方でも触れた、ページの圧縮配信を行います。
こちらも設定は簡単で、httpd.confで以下のモジュールをロードするようにし(コメントアウトを外し)、

LoadModule deflate_module modules/mod_deflate.so

httpd.confもしくはssl.confに以下を追加するだけ。

<IfModule mod_deflate.c>
    SetOutputFilter DEFLATE
</IfModule>

こうすることで、配信時に圧縮してから配信してくれるようになります。

ただ、こうすると私のようなネットワーク赤ちゃんからすると「都度圧縮→配信するから圧縮処理が挟まる分良くてトントン、最悪遅くなるのでは?」「都度圧縮してたらサーバー負荷もどうなの?」とか思いました。

前者については圧縮率によるようです。圧縮率が高いファイルなら高速化の恩恵の方が大きく、逆に圧縮率が低ければ当然ファイルの容量はあまり変わらず圧縮処理だけが入る感じなので逆効果になることもあり、ということのようで、圧縮するファイルの種類はチューニングしてあげる必要がありそうです。

後者は部分的には予想通りみたいですが、極端に上がることはないみたいです。

所感

Tailwind CSS以外は割と簡単な設定でかなり効果があるので、ぜひお試しください。
Tailwind CSSも慣れるのに時間がかかるのと、既存プロジェクトを置き換えるとかになると大変そうですが、パフォーマンス以外の恩恵も大きい(従来のcssファイル分ける方法だと、HTML構造とcssファイルとにらめっこしてスタイルの作りがどうなっているか調べる必要があった)のでお勧めです。

関連リンク

記事の作成者のA.W.のアイコン

この記事を書いた人

A.W.
茨城県在住Webエンジニアです。 PHPなどを業務で使用しています。 趣味ではGoやNuxt、Flutterをやってます。

Comment