この記事は GRIPHONE Advent Calendar 2020 20日目の記事です。
こんにちは。フロントエンドエンジニアの小山です。
今年の3月頃、Studio MGCMが運用するマジカミ公式サイトのLighthouseスコアを確認したところ20点台で、これはマズいということになり改善を目指すことになりました。
大まかな問題点だった箇所
- 画像がpngかつ軽量化が甘かった
- レンダリング前に読み込んでいるコンテンツが多かった
- ビルドする際にファイルの分割が大きすぎた
画像がpngかつ軽量化が甘かった問題
まずはメインビジュアル部分に着目しました。
使っている画像はすべてpng画像。且つ、ある程度の画面サイズに対応できるようにかなり大きめの画像を使っていた。
Lighthouseの警告を確認したところ…
- 適切なサイズの画像を使え
- 次世代画像フォーマットに変えろ
とのこと。
画像のサイズ調整
ちょっと大きすぎるぐらいの画像サイズだったので画像を適宜小さくして圧縮。ここまでは単純作業。
画像のフォーマットをwebpに変更
Lighthouseが言うには「次世代画像フォーマットに変えろ」、つまり「webp」を使えとのこと。
webpとは→https://ja.wikipedia.org/wiki/WebP
手持ちの画像をwebpに変更するにはwebのツールを使ったりもできますが今回はcwebpを使ってローカルで対応することにしました。
cwebpのインストール
brew install webp
cwebpの使い方
使い方は結構簡単で「-q」オプションで圧縮率(クオリティ)の設定、「-o」オプションで出力先の設定をするだけです
cwebp -q 80 foo.jpg -o foo.webp
これを利用してメインビジュアルに使っている画像を適宜webpに変換していきます。
webpに変換した画像はimgタグにそのまま入れられないので、pictureタグに変換して利用します
<picture alt="マジカミ">
<source type="image/webp" srcset="logo.webp" decoding="async" alt="マジカミ">
<img src="logo.png" decoding="async" alt="マジカミ">
</picture>
webpに対応していないブラウザ用に元のpng画像も配置しています。
これで画像の問題は解決しました。
レンダリング前に読み込んでいるコンテンツが多かった問題
マジカミ公式サイトトップページではレンダリングする前に以下のものを読み込んでいました。
- 新着ニュース記事
- Twitterのタイムライン埋め込み
- トップに表示するバナーの一覧
- 画像などの各種静的コンテンツ
隠れているコンテンツを後回しにする
サイトのデザイン上、新着ニュース記事とTwitterのタイムラインは画面横のタブをクリックされるまで表示されません。
これを考慮して、タブがクリックされてから取りに行くことにしてレンダリング前の取得から外します。
バナー一覧の取得を遅らせる
バナー一覧に関しては、単純にsetTimeoutを利用し3000ms遅らせることにします。3000msの根拠はメインビジュアルのアニメーションが終わるタイミングがそれぐらいなんのでと言うこれもまた単純な理由です。
lozadを使って画像などの各種静的コンテンツを遅延ロード
静的コンテンツの遅延ロードにはLozad.jsを利用しました。
画像のsrc属性だけでなく、videoタグ、さらにはcssのbackground-imageまでも対応しているのでなかなか便利です。
詳しくはこちら → Lozad.js(https://apoorv.pro/lozad.js/)
ビルドする際にファイルの分割が大きすぎた問題
マジカミ公式サイトはNuxt.jsで作られているのですがビルドする際のファイル分割を特に意識していなかったため、ページによっては必要のないプラグインやコンポーネントを多数読み込んでしまっていました。
そこでWebpack Bundle Analyzerを利用して、バンドルファイルの大きさを確認、適宜リファクタリングを行いました。
https://github.com/webpack-contrib/webpack-bundle-analyzer
リファクタリングの中で全ページ共通で呼ばれているプラグインを一括設定から外して必要なコンポーネント内でのみimportするよう調整などを行います。
結果
そのほかにもLighthouseの指示に従い、細かに調整した結果…
スコアを平均して90点台まで持っていくことができました! ( ・´ー・`)どや
こちらがPCブラウザ版表示の結果なので引き続きモバイル版でもいいスコア出せるように調整していきたいと思います。