🚪

DevToolsでパフォーマンス計測をして新世界の扉をひらく

2024/12/12に公開

本記事は、Lancers(ランサーズ) Advent Calendar 2024 の12日目の記事です。

昨日は@yukiyama0508さんによるゼロから始める受託開発 - 思わぬ失敗の連続談でした

はじめに

mizchiさんによる「LAPRAS 公開パフォーマンスチューニング」~調査編~

先日このイベントに参加しまして
ゆるふわでDevTools使ってた自分としては目から鱗だったので
実際に計測を試してみて少しでもモノにしたい…!というモチベでやってます

Webエンジニア、インフラエンジニアの方はこの動画を見た方がいいです

イベントに関する自分なりのメモも一応貼っときます
https://zenn.dev/shirasud/scraps/ef962caffb83c3

免責

  • DevToolsの使い方は説明しません
  • 自分はパフォーマンス計測、チューニングに詳しい人ではないです
    • これ解釈違うよ、この観点見た方がいいよみたいなのは教えてください
    • だいぶ遠回りをしてチューニングしてる気がするので長文になってます
  • INPは計測しません
    • lighthouseで計測できないので今回は省きます

サービスについて

https://www.lancers.jp/

ランサーズは仕事を依頼したいクライアントと
仕事を受注したいランサーのマッチングを提供するプラットフォームです

その特性上、TOPページが2つあります。この2つを対象に計測していきます

  • 仕事を依頼したいクライアント向けのTOPページ (https://lancers.jp)
    • レンダリング方法: NextJSを用いたSG (Static Generation)
  • 仕事を受注したいランサー向けのTOPページ (https://lancers.jp/l)
    • レンダリング方法: CakePHPを用いたSSR (Server Side Rendering) + 一部React

CoreWebVitals と NonCoreWebVitals

LCP、CLS、INP、FCP、TBTあたりはこの記事で頻出ワードとして出てきます

Web Vitalsは、Googleが導入したウェブサイトのユーザー体験(UX)を向上させるための取り組みです。PerplexityいわくCoreWebVitalsはフィールドデータを元に設計されていて、NonCoreWebVitalsの方はフィールドデータ+一部ラボデータを元に設計されているようです

Chrome User Experience Reportを確認

Googleが提供するツールで、Chrome User Experience Report (CrUX) が時系列でまとまっているサービスです。これと自分のマシンで計測するlighthouseなどのラボデータとでズレが極端にないか確認しつつ進めると良いみたいです

https://cruxvis.withgoogle.com/

クライアントTOP

INP以外はクリアしてるっぽい

ランサーTOP

おや…?2024/10/19 - 2024/11/15からCLSが悪化してる
LCPについても若干上がり傾向に見える

lighthouseでスコア計測

Chorome拡張がない状態のプライベートブラウザで計測
デフォルト設定で3回くらいまわしてますが結構スコアの差が出ました

クライアントTOP

スコアはだいたい64-80くらいで、LCPが赤になるかオレンジになるかの差分がありました

LCPが確定する要素はメインビジュアルのところ

ツリーマップは綺麗に見える。でかいのはほとんどGTM

ランサーTOP

スコアはだいたい26-36くらいで、CLSがオレンジでそれ以外は全て赤
LCPが15.2sとだいぶ遅く見える(クライアントTOPは4.2s)

LCPが確定する要素は…これどこの画像だ?後ほどPerformanceタブにて確認する

ツリーマップはheader.jsがとにかくでかいですね

サードパーティタグをブロックしてスコアのポテンシャルを見る

ポテンシャルが気になってしまったので先にブロックを試します
Networkタブで3rd Partyのフィルタを使ったらわかりやすかったです

クライアントTOP

スコアは74-82(ブロックなしで64-80)
スコアはそこまで変わらずですが、TBTが840ms → 0msになってる…!
GTM経由で読んでるタグで何かブロッキングが発生している可能性ありますね

Treemapもいい感じにみえる

ランサーTOP

スコア幅は46-51(ブロックなしで26-36)
スコアも結構変わってます。datadogのタグが少しパフォーマンス影響あるかもしれないですね
TBTが500msくらい減ったけど、まぁ改善しがいがありそうな結果でした

Treemapはheader.jsがでかすぎて他が見えない

ランサーTOPのパフォーマンスチューニング

これまでの計測結果から、以降はランサーTOPのチューニングを行ないます

  • クライアントTOPは、パフォーマンスに大きな問題がなさそう(細かい改善点はある)
  • ランサーTOPは、LCP、CLSを中心にチューニングが必要なレベル

なんとなくheader.jsをブロックしてみた

スコア幅は48-54 (header.jsブロック前と比較して+3くらい)
LCPが大幅に早くなりました(14.3s → 7.8s)

スライダープラインのsplideがデカく見えるけど29KBなので問題なし

Performanceタブを見てみる

スロットリングは、以下ですがlighthouseに寄せるためにslow4Gで見たりもしました
シンプルな状態で見たかったので引き続きサードパーティもブロックして見てます

CLSの改善

アニメーションでめちゃめちゃわかりやすくレイアウトシフト

override contentでCSSを上書きして高さを確保したらレイアウトシフト消えた

CLSはこれでクリア

LCPの改善

何がLCP確定の要素になってるかlighthouseでわからなかったけど
これを見るにおそらくトップビジュアルのスライダーの1枚目?

スライドの1枚目がLCP確定の要素というのもまだ仮説でしかなかったので
画像多すぎ?むしろスライダーをやめる選択肢も?と思い
試しにHTMLをOverride Contentしてスライドショーの枚数を減らしてみる

LCPのタイミングは早まらず
メインスレッドで「XHR Load」の後にLCPが確定しているのが気になった

もう少し拡大するとheader.jsのダウンロードがわかりやすく時間かかってるのと
その後のメインスレッドでロングタスクにつながっているのがわかる

LCP確定要素の画像のダウンロードは終わってるけど
この処理でレンダリングブロックされてるように見える

やっぱりheader.jsかーとなってブロックしてみたらLCPが2000ms -> 900msに改善

試しに減らしてたスライダー画像を戻してもLCPは900msだから枚数はそんな関係なかった

大きめな画像に全部preloadを入れてみた

これでもLCPが真っ赤なままだったのでslow 4Gに切り替えて色々やってみる
preloadを入れまくることで読み始めは早くなったが、
結局のところこの画像のサイズが大きいのかもしれない?と疑い始める

<link rel="preload" href="画像パス" as="image">

ボトルネックがレンダリングブロックからNetworkに変わってることに気づく

やっぱりファーストビューで読み込むwebpが重い(191kB)

NetworkタブでSizeソートをしたら一目瞭然だった

クライアントTOPの軽量webpを拝借(38.2kB)

無事LCPが早まりました(6.5s -> 2s)

これ以上LCPを早めるにはどうすれば…?

lighthouseにヒントがあった。半分ぐらい未使用なCSSを消してOverrideしてみた

ここまでやってlighthouseのスコアも概ね満足いく感じになりました

まとめ

パフォーマンス計測楽しい…!

見返してみるとだいぶ遠回りで意味ないことをしてた気がしますが
Performanceタブ何もわからん、lighthouse使ったことないみたいな状態から
計測して改善してボトルネックが変わっていく様まで観測できてる自分スゴい!と自己効力感に溢れています

mizchiさんが勉強会で「Performanceタブは仮説をもって見ないと読み解けない」と言っていましたが、それを身をもって痛感しました。

仮説を立てる能力はパフォーマンスチューニングを繰り返しやっていくしかないのと、
ブラウザのレンダリングプロセスなどをもっと学ばないと磨かれないと思うので引き続きやっていきます

読んでいただいた方ありがとうございます。以上です

明日は、yosukehiyoshiさんによる2024年 エンジニア組織の取り組みを振り返るです

ランサーズでは、一緒に働けるメンバーを募集しています!
https://recruit.jobcan.jp/lancers01/list/all/all

ランサーズ株式会社

Discussion