javascriptをgzip圧縮してLighthouseのスコアを改善する

LaravelアプリケーションのLighthouseのスコアを改善していく企画の3日目です。
前回、font-awesome関連の不要なファイルを削除してjsのサイズを削減した結果、Lighthouseのスコアが9点から11点に向上しました。
今回も引き続き、改善を進めていきます。
まずは計測していきましょう!!!!

Lighthouseで計測する

んんんんんンンンンン????

Lighthouseの計測結果

おおおおおおんんんンンンン???

Lighthouseの計測結果の重要な部分
あまりにも絵文字が多過ぎやしないだろうか…… - りんごが好きなのでぃす
困惑する顔

何故か前回よりスコアが下がってました。(というか0点てお前)
改善提案(Opportunities)の欄を見るとどうやらjsのファイルサイズが増えてしまったようです。

JSの内訳を確認する。

前々回に導入したwebpack-bundle-analyzeを使ってJSの内訳を可視化して、前回のものと見比べてみる。

今回

現在の出力ツリーマップ

前回

前回の出力ツリーマップ

あきらかにresources以下が肥大化している。
resources以下は自分が書いたコードなので機能追加した時に何かやらかしてしまったっぽい。

原因を調べる。

これは仮説だが、vueコンポーネントのstyleタグでサイズの大きいリソースを読み込むとコンポーネントの数だけ展開されてサイズが一気に肥大化する??
例えば以下の様なコードがあったとして、空にするとファイルサイズはどうなるか。

修正前のstyleタグ
修正後のstyleタグ

ファイルサイズが約1/5になった。(79KB → 16KB)

修正前のファイルサイズ
修正後のファイルサイズ

というのも、肥大化した原因に心当たりがあって、機能追加した時に多数のコンポーネントに、以下の様なstyleを追記していったからだ。
(PC版とSP版で異なるスタイルを当てている。またそのためのユーティリティをbootstrapから引き込んでいる。)
これがコンポーネントの数だけコードが展開されているとするとそこそこのファイルサイズになるはず。

@import "~bootstrap/scss/bootstrap-grid"
            @include media-breakpoint-up(xs) {
                ...(中略)....
            }
            @include media-breakpoint-up(sm) {
                ...(中略)....
            }

上記の記述をコメントアウトして再度JSの内訳を確認すると、明らかにresources以下が削減されたので、多数のvueコンポーネントのstyleタグで大きめのリソースを参照しているのが原因と言える。

ツリーマップ

Gzip圧縮する

原因は掴めたのだが、JSの内訳(ツリーマップ)を眺めていると「Gzipにすると531KBになるぜ」という記述を見つけた。
これが本当ならめっちゃ削減できますやんという事で先にGzip圧縮をやってみる事にした。

Gzip後のサイズまで教えてくれるツリーマップ

Webpackの公式ドキュメントを参考にCompressionWebpackPluginを導入してビルドする。
以下の様に、.gzが付いたファイルが追加で生成された。

gzip圧縮されたjsファイルが出力されている図

どうやってgzipファイルを配布するのか?

nginxでは以下の様にgzip onを設定すれば自動的に圧縮されて配信されるらしい。
ただし、配信する時に毎回圧縮するので処理にオーバーヘッドが加わるとの事。

gzip on;
gzip_types text/css application/javascript application/json application/font-woff application/font-tff image/gif image/png image/jpeg application/octet-stream;

圧縮は実行時に行われるため、処理にかなりのオーバーヘッドが加わり、パフォーマンスに悪影響を及ぼす可能性があります。

https://docs.nginx.com/nginx/admin-guide/web-server/compression/

毎回圧縮するのはちょっとなぁ。
もう少し調べた所、gzip_static: onなら「リクエストされたファイルパス + .gz」 のファイルを自動的に返してくれるらしい。
これならwebpackのプラグインと相性ばっちり。

/path/to/fileのリクエストを処理するために、NGINXはファイル/path/to/file.gzを見つけて送信しようとします。ファイルが存在しない場合、またはクライアントがgzipをサポートしていない場合、NGINXは非圧縮バージョンのファイルを送信します。

https://docs.nginx.com/nginx/admin-guide/web-server/compression/#sending-compressed-files

ミドルウェア周りのデプロイは自動化されているので、nginxの設定ファイルを書き換えてプッシュして変更完了!

Gzip導入前後で比較する

導入前。
ファイルサイズが3.5MBでGzip圧縮も掛かっていない。ダウンロードに7秒(笑)掛かっている。

gzip導入前のネットワークタブ
gzip導入前のレスポンスヘッダ

導入後。
Gzip圧縮が適応されファイルサイズが531KBになっている!(85%の削減)
ダウンロードも1秒になった。

gzip導入後のネットワークタブ
gzip導入後のレスポンスヘッダ

再度、Lighthouseで測定する

いざ!!!!!!!!!

ハイッ!
9点!!! 前々回の点に戻った!!!!!

gzip導入後のLighthouseの測定結果

「javascriptをgzip圧縮してLighthouseのスコアを改善する」への1件のフィードバック

コメントする