EBISUCOM エビスコム
  1. 著者NOTE

GatsbyJSのパフォーマンスを
Lighthouse 6(Web Vitals)に合わせて最適化する

GatsbyJSで作成した『Webサイト高速化のための 静的サイトジェネレーター活用入門』のサンプル(https://gatsby-essentials.netlify.app/)を Lighthouse 6 で測定すると、5.6のときよりも全体的にパフォーマンスのスコアが下がります。

Lighthouse 5.6.0での結果
Lighthouse 6.0.0での結果

これらは、Lighthouse Metrics(https://lighthouse-metrics.com/)で Lighthouse のバージョンを切り替えて測定したものです。リストアップされた数値は6つのロケーションごとのパフォーマンススコアです。

ここではスコアが下る要因を確認し、Lighthouse 6 に合わせて調整する方法を模索してみます。

Lighthouse 6 に導入された新しい指標

Lighthouse 6 には Google の「Web Vitals」という新しい指標が導入されています。UXの向上を目指したもので、2021年以降にはランキング要因になることも発表されました。

現在のところ、Web Vitals は3つの指標で構成されています。

Web Vitals(https://web.dev/vitals/)より引用

LCP(Largest Contentful Paint)
大きいコンテンツが表示されるまでの時間です。2.5sec以下であることが求められます。

FID(First Input Delay)/ TBT(Total Blocking Time)
ユーザーによる操作が受け付けられるようになるまでの時間で、100ms以下であることが求められます。ただし、ユーザー不在のテスト環境であるLighthouseでは、FID の代わりに TBT(Total Blocking Time)が使用されます。TBTは300ms以下であることが求められます。

CLS(Cumulative Layout Shift)
レイアウトシフト(画像の表示などでレイアウトがずれる現象)の発生頻度です。できるだけ発生しないほうがよく、「0.1」以下であることが求められます。


GatsbyJSで作成したサンプルの場合、TBTに大きな問題は見られませんでした。 CLSについても gatsby-image が画像の表示スペースを確保してくれるため、レイアウトシフトは発生せず、測定値も「0」になります。
問題がありそうなのは LCP(Largest Contentful Paint)です。

Lighthouse 6 で追加されたWeb Vitalsの指標
パフォーマンススコアの詳細

LCP(大きいコンテンツが表示されるまでの時間)を確認する

コンテンツが表示されるまでの時間に関しては、Lighthouse 5.6 では FMP(First Meaningful Paint)が指標となっており、サンプルでも問題のない計測値が出ていました。
しかし、Lighthouse 6 の LCP では表示までにずいぶんと時間がかかるようになっています。

そこで、Chromeのデベロッパーツールで「Performance」を確認してみると、FMPとLCPの間に大きな開きがあることがわかります。

gatsby-imageで表示したヒーローイメージに対し、FMPはプレースホルダ(base64画像)が表示された時点で、LCPは画像(hero.webp)の表示が完了した時点で計測されています。

LCPを改善するためには、FMPとLCPの間の時間を短縮することが必要です。

FMPとLCPの間の時間を短縮する

短縮するための解決方法を考えてみます。基本的な方法は次の2択です。

A. 画像の読み込み速度を上げる

画像をより速く読み込むためには、サーバーの改善などが必要になります。
ただし、すでに高速な環境を使っている場合には、これ以上改善するのは困難です。

B. 画像のファイルサイズを小さくする

画像のファイルサイズを小さくしようとした場合、さらに圧縮する、より圧縮率の高いフォーマットに変える、または画像のサイズそのものを小さくすることになります。

サンプルではgatsby-imageを使用し、WebPフォーマットも採用して最適化を行っています。

画像の大きさを小さくしようとした場合は、デザインの変更まで考えなければなりません。
依頼されたデザインに合わせてページを作っている状況であれば、この選択肢はないでしょう。

そのため、これ以上ファイルサイズを小さくするのも困難です。

では、他にできることはないのでしょうか。

gatsby-imageの場合

gatsby-imageの場合は、Lazy Loadによる読み込み待ちの時間と、プレースホルダからのフェードインの時間があります。これらを短縮することを考えます。

どちらも gatsby-image の設定として調整できます。

    <section className="hero">
      <figure>
        <Img
          fluid={data.hero.childImageSharp.fluid}
          alt=""
          style={{ height: "100%" }}
          loading="eager"
          durationFadeIn={100}
        />
      </figure>

ここでは Lazy Loadをオフにするため、loadingを「eager」と指定しています。すると、書籍 P.81 のような順で読み込まれていた画像(hero.webp)が、他のリソースと並行して先に読み込まれるようになります。

次に、フェードインは完全にオフにすることもできますが、プレースホルダからの切り替えがパタパタした印象になり、細かな動きの見えるユーザーからは「gatsby-imageの安定感がなくなる」と不評でした。そのため、durationFadeInを追加し、標準では500msになっているフェードインを「100ms」に変更しています。

以上のように設定して Performance を確認すると、次のようにFMPとLCPの間の時間が短縮されたことがわかります。

Lighthouse 6 で計測されるパフォーマンススコアも改善します。

たとえば US EAST の LCP の場合、改善前は 2.6s だったものが 1.9s になっており、フェードインの調整とLazy Loadをオフにした効果がはっきりと現れています。

こうなってくると、サイト全体で一律の設定で利用するのではなく、ポイントごとにきちんと選択し、gatsby-imageのパラメータを調整していく必要がありそうです。もっとも、大きなアイキャッチがメインとなっている現在のページデザインそのものが変わっていくのかもしれませんが…


なお、Lighthouse 6 で追加された新しい指標がサイトに与える影響は Gatsby の GitHub でも取り上げられていますので、何らかの対策が講じられるかもしれません。

Worse performance results with Lighthouse v6 (?) #24332

この指標がWebデザインにどのような影響を与えていくのでしょうか。

Webサイト高速化のための 静的サイトジェネレーター活用入門

2020年6月 マイナビ出版刊
B5変型 320ページ / 978-4839973001

HTML&CSS コーディング・プラクティスブック

デザインカンプと指示書に従い、
Webページをコーディングしてみる実践シリーズです。