ウェブ パフォーマンスを簡単に - Google I/O 2018 エディション

Google IO 2018 では、ウェブ パフォーマンスの改善を容易にするツール、ライブラリ、最適化手法の概要を発表しました。ここでは、Oodles Theater アプリを使用して、これらの機能について説明します。また、予測読み込みと新しい Guess.js イニシアチブのテストについても説明します。

Addy Osmani
Addy Osmani
Ewa Gasperowicz

過去 1 年間、Google はウェブの高速化とパフォーマンスの向上を図るために、かなり忙しく活動してきました。これにより、新しいツール、アプローチ、ライブラリが生まれました。この記事では、それらについて説明します。前半では、Oodles Theater アプリの開発時に実際に使用した最適化手法について説明します。後半では、予測読み込みと新しい Guess.js イニシアチブに関するテストについて説明します。

パフォーマンスの必要性

インターネットの通信量は年々増加しています。ウェブの状況を確認すると、モバイル ページの平均サイズは約 1.5 MB で、そのほとんどが JavaScript と画像であることがわかります。

ウェブサイトのサイズの増大は、ネットワーク レイテンシ、CPU の制限、レンダリング ブロック パターン、不要なサードパーティ コードなどの他の要因とともに、複雑なパフォーマンス パズルにつながっています。

ほとんどのユーザーは、スピードを自分のニーズの UX 階層の最上位に位置付けていると評価します。ページの読み込みが完了するまで、あまりできることがないため、これは驚くべきことではありません。ページから価値を引き出すことはできません。その美しさを楽しむこともできません。

UX 階層ピラミッド
図 1. ユーザーにとって速度はどの程度重要ですか?(Speed Matters、Vol. 3)

パフォーマンスはユーザーにとって重要ですが、最適化を開始する場所を見つけるのは秘密のようでもあります。幸い、この作業に役立つツールがあります。

Lighthouse - パフォーマンス ワークフローのベース

Lighthouse は Chrome DevTools の一部で、ウェブサイトを監査し、改善方法のヒントを提供します。

Google は最近、日常的な開発ワークフローで非常に役立つ新しいパフォーマンス チェックをリリースしました。

Lighthouse の新しい監査
図 2. 新しい Lighthouse 監査

では、Oodles Theater アプリという実用的な例で、これらの機能の活用方法を見てみましょう。これは小さなデモ用ウェブアプリで、お気に入りのインタラクティブな Google Doodle を試したり、ゲームをプレイしたりできます。

アプリの開発にあたっては、できるだけ高いパフォーマンスを実現することを目標としました。最適化の開始点は Lighthouse レポートでした。

Oodles アプリの Lighthouse レポート
図 3. Oodles アプリの Lighthouse レポート

Lighthouse レポートに表示されるアプリの最初のパフォーマンスは非常に悪かったです。3G ネットワークでは、最初の有意なペイント、つまりアプリがインタラクティブになるまで 15 秒間待たなければなりませんでした。Lighthouse は、サイトの問題を大量に検出しました。全体的なパフォーマンス スコアは 23 で、そのことを如実に反映しています。

ページの重量は約 3.4 MB で、削減が急務でした。

これが最初のパフォーマンスの課題、つまり全体的なエクスペリエンスに影響を与えることなく簡単に削除できるものを見つけることから始まりました。

パフォーマンスの最適化に関する最適化案

不要なリソースを削除する

空白文字とコメントは、安全に削除できる明らかなものです。

軽量化によるメリット
図 4.JavaScript と CSS を圧縮する

Lighthouse では、非圧縮 CSS と JavaScript の監査でこの機会を強調しています。ビルドプロセスに webpack を使用していたため、圧縮を行うには Uglify JS プラグインを使用しました。

圧縮は一般的なタスクであるため、使用しているビルドプロセスに応じて、既製のソリューションを見つけることができます。

この分野で役立つ監査のもう 1 つに、テキスト圧縮の有効化があります。非圧縮ファイルを送信する理由はありません。最近では、ほとんどの CDN ですぐにサポートされます。

コードは Firebase Hosting を使用してホストしていましたが、Firebase はデフォルトで gzip 圧縮を有効にします。妥当な CDN でコードをホストしたおかげで、無料でこれを実現できました。

gzip は非常に一般的な圧縮方法ですが、ZopfliBrotli などの他のメカニズムも注目を集めています。Brotli はほとんどのブラウザでサポートされています。バイナリを使用して、サーバーに送信する前にアセットを事前に圧縮できます。

効率的なキャッシュ ポリシーを使用する

次のステップは、不要なリソースを 2 回送信しないようにすることです。

Lighthouse の「非効率キャッシュ ポリシー」の監査により、キャッシュ戦略を最適化してこの目的を達成できることがわかりました。サーバーに max-age 有効期限ヘッダーを設定することで、ユーザーが繰り返しアクセスしたときに、以前にダウンロードしたリソースを再利用できるようにしました。

理想的には、できるだけ多くのリソースを可能な限り安全にキャッシュに保存し、検証トークンを提供して、更新されたリソースを効率的に再検証できるようにします。

未使用のコードを削除する

ここまでは、不要なダウンロードの明らかな部分を削除してきましたが、それほど明らかでない部分はどうでしょうか。たとえば、使用されていないコードなどです。

DevTools のコード カバレッジ
図 5.コード カバレッジを確認する

アプリに、実際には必要のないコードが含まれていることがあります。これは、アプリの開発期間が長い場合や、チームや依存関係が変更された場合に特に発生します。また、孤立したライブラリが残されることもあります。まさにこの状況です。

最初は、マテリアル コンポーネント ライブラリを使用してアプリのプロトタイプをすばやく作成していましたが、カスタム ルック&フィールに移行したため、そのライブラリは完全に忘れてしまいました。幸い、コードカバレッジ チェックにより、バンドルで再発見できました。

コード カバレッジの統計情報は、DevTools でアプリケーションの実行時間と読み込み時間の両方について確認できます。下のスクリーンショットには、2 つの大きな赤いストライプがあります。CSS の 95% 以上が未使用で、JavaScript も大量に未使用でした。

Lighthouse では、使用されていない CSS ルールの監査でもこの問題が確認されています。400 KB 以上の削減が見込まれました。そこで、コードに戻り、そのライブラリの JavaScript と CSS の両方の部分を削除しました。

MVC アダプタをドロップすると、スタイルは 10 KB に減少します。
図 6. MVC アダプターをドロップすると、スタイルは 10 KB に減少します。

これにより、CSS バンドルが 20 倍小さくなりました。これは、2 行の短い commit としては非常に良い結果です。

もちろん、パフォーマンス スコアは向上し、操作可能になるタイミングも大幅に改善されました。

ただし、このような変更では、指標とスコアを確認するだけでは十分ではありません。実際のコードを取り除くことはリスクが伴うため、潜在的なリグレッションに常に注意する必要があります。

コードの 95% は使用されていませんでしたが、どこかに 5% 残っています。あるコンポーネントが、そのライブラリのスタイル(塗り絵スライダーの小さな矢印)をまだ使用していたようです。ただし、非常に小さいため、これらのスタイルを手動でボタンに組み込むことができました。

ライブラリがないためボタンが破損した
図 7. 1 つのコンポーネントで、削除されたライブラリが引き続き使用されていました

コードを削除する場合は、視覚的なリグレッションの可能性を防ぐために、適切なテスト ワークフローが確立されていることを確認してください。

膨大なネットワーク ペイロードの回避

大きなリソースはウェブページの読み込みを遅らせる可能性があることは認識しています。ユーザーの費用やデータプランに大きな影響を与える可能性があるため、この点に注意することが非常に重要です。

Lighthouse では、膨大なネットワーク ペイロードの監査により、一部のネットワーク ペイロードに問題があることを特定できました。

過大なネットワーク ペイロードを検出する
図 8. 巨大なネットワーク ペイロードを検出する

ここでは、3 MB を超えるコードが送信されていることがわかりました。これは、特にモバイルでは非常に大きな量です。

このリストの一番上には、圧縮されていないコードが 2 MB の JavaScript ベンダー バンドルがあることがハイライト表示されています。これは webpack でも問題として指摘されています。

よく言われるように、リクエストを送信しないことが最速のリクエストです。

理想的には、ユーザーに配信するすべてのアセットの価値を測定し、それらのアセットのパフォーマンスを測定し、最初のエクスペリエンスで実際に配信する価値があるかどうかを判断する必要があります。これらのアセットは、アイドル時に遅延、遅延、処理が行われることがあるため。

Google の場合は、JavaScript バンドルが大量に存在するため、JavaScript コミュニティに豊富な JavaScript バンドル監査ツールが存在するという幸運に恵まれました。

JavaScript バンドルの監査
図 9. JavaScript バンドルの監査

最初は webpack バンドル アナライザから始めて、解析された JavaScript が 1.6 MB の Unicode という依存関係が含まれていることがわかりました。

その後、エディタに移動し、Visual Code の Import Cost プラグインを使用して、インポートするすべてのモジュールの費用を可視化できました。これにより、このモジュールを参照しているコードを含むコンポーネントを特定できました。

その後、別のツールである BundlePhobia に切り替えました。このツールを使用すると、任意の NPM パッケージの名前を入力し、圧縮および gzip 圧縮されたときの推定サイズを実際に確認できます。使用しているスラッグ モジュールの代わりに、容量がわずか 2.2 KB のものが見つかったため、これを変更しました。

これはパフォーマンスに大きな影響を与えました。この変更と、JavaScript バンドルのサイズを削減するための他の機会の発見により、2.1 MB のコードが削減されました。

これらのバンドルの gzip 圧縮と圧縮後のサイズを考慮すると、全体で 65% の改善が見られました。プロセスとして行う価値があることがわかりました。

そのため、一般的に、サイトやアプリで不要なダウンロードを排除するようにしてください。アセットのインベントリを作成してパフォーマンスへの影響を測定すると、大きな違いを生む可能性があります。アセットを定期的に監査するようにしてください。

コード分割による JavaScript の起動時間の短縮

ネットワーク ペイロードが大きいとアプリに大きな影響を与えますが、JavaScript も大きな影響を与える可能性があります。

JavaScript は最も高価なアセットです。モバイルで JavaScript の大きなバンドルを送信すると、ユーザーがユーザー インターフェース コンポーネントを操作できるようになるまでの時間が遅れる可能性があります。つまり、実際には何も意味のない操作を UI 上で行っている可能性があります。そのため、JavaScript の費用がこれほど高くなる理由を理解することが重要です。

ブラウザが JavaScript を処理する仕組みは次のとおりです。

JavaScript の処理
図 10.JavaScript 処理

まず、そのスクリプトをダウンロードする必要があります。JavaScript エンジンがそのコードを解析し、コンパイルして実行する必要があります。

これらのフェーズは、デスクトップ マシンやノートパソコン、ハイエンド スマートフォンなどのハイエンド デバイスではそれほど時間がかかりません。しかし、中央値のスマートフォンでは、このプロセスに 5 ~ 10 倍も長くかかることがあります。これがインタラクティビティを遅らせる原因です これをカットすることが重要です

アプリでこのような問題を検出できるように、Lighthouse に新しい JavaScript 起動時間の監査を導入しました。

JavaScript の起動時間
図 11. JavaScript の起動時間の監査

Oodle アプリの場合、JavaScript の起動に 1.8 秒かかったことがわかります。すべてのルートとコンポーネントを 1 つのモノリシックな JavaScript バンドルに静的にインポートしていました。

この問題を回避する方法の一つが、コード分割を使用することです。

コード分割はピザのようなものです

コード分割とは、ユーザーにピザ全体分の JavaScript を提供するのではなく、必要に応じて一度に 1 スライスだけ提供するという考え方です。

コード分割は、ルートレベルまたはコンポーネント レベルで適用できます。React、React Loadable、Vue.js、Angular、Polymer、Preact、その他の複数のライブラリで適切に機能します。

アプリケーションにコード分割を組み込み、静的インポートから動的インポートに切り替え、必要に応じて非同期でコードを遅延読み込みできるようにしました。

動的インポートによるコード分割
図 13. 動的インポートによるコード分割

これにより、バンドルのサイズが縮小され、JavaScript の起動時間が短縮されました。0.78 秒に短縮され、アプリの速度が 56% 向上しました。

一般に、JavaScript を多用するエクスペリエンスを構築する場合は、ユーザーに必要なコードのみを送信してください。

コード分割などの概念を活用し、ツリー シェイキングなどの概念について検討します。また、webpack を使用している場合にライブラリ サイズを小さくする方法については、webpack-libs-optimizations リポジトリをご覧ください。

画像を最適化する

画像読み込みのパフォーマンスに関するジョーク

Oodle アプリでは、多くの画像を使用しています。残念ながら、Lighthouse は Google ほど熱心ではありませんでした。実際、Google は画像に関する 3 件の監査すべてで不合格となりました。

画像の最適化を忘れたり、画像のサイズを適正化したりせず、他の画像形式を使用することで利益を得ることができました。

画像監査
図 14. Lighthouse イメージの監査

まず、画像の最適化から始めました。

1 回限りの最適化ラウンドの場合は、ImageOptimXNConvert などのビジュアル ツールを使用できます。

より自動化されたアプローチでは、imagemin などのライブラリを使用して、ビルドプロセスに画像最適化ステップを追加します。

これにより、今後追加される画像が自動的に最適化されます。Akamai などの CDN や、CloudinaryFastlyUploadcare などのサードパーティ ソリューションは、包括的な画像最適化ソリューションを提供しています。これらのサービスに画像をホストすることもできます。

費用やレイテンシの問題でそうしたくない場合は、ThumborImageflow などのプロジェクトでセルフホストの代替手段を利用できます。

最適化前と最適化後
図 15.最適化前と最適化後

背景の PNG は、webpack でサイズが大きいと報告されました。これは当然のことでした。ビューポートに合わせてサイズを調整し、ImageOptim で実行した結果、100 KB まで削減できました。これは許容範囲内です。

サイト上の複数の画像に対してこの操作を繰り返すことで、ページ全体の重量を大幅に削減できました。

アニメーション コンテンツに適した形式を使用する

GIF は高額になることがあります。驚くべきことに、GIF 形式はそもそもアニメーション プラットフォームとして意図されたものではありません。そのため、より適切な動画形式に切り替えることで、ファイルサイズを大幅に削減できます。

Oodle アプリでは、ホームページの導入シーケンスとして GIF を使用していました。Lighthouse によると、より効率的な動画形式に切り替えることで、7 MB 以上節約できる可能性があります。当社のクリップの重み付けは約 7.3 MB で、妥当なウェブサイトとしては大きすぎるため、代わりに mp4 と WebM という 2 つのソースファイルを含む動画要素に変換して、幅広いブラウザに対応できるようにしました。

アニメーション GIF を動画に置き換える
図 16.アニメーション GIF を動画に置き換える

FFmpeg ツールを使用して、アニメーション GIF を mp4 ファイルに変換しました。WebM 形式にすると、さらにサイズを削減できます。ImageOptim API は、このような変換を自動的に行います。

ffmpeg -i animation.gif -b:v 0 -crf 40 -vf scale=600:-1 video.mp4

この変換のおかげで、体重を 80% 以上削減できました。これにより、サイズは約 1 MB になりました。

それでも、1 MB は、特に帯域幅が制限されているユーザーにとって、ワイヤーを押し下げる大きなリソースです。幸い、Effective Type API を使用して、低い帯域幅であることを認識し、代わりにはるかに小さい JPEG を提供できます。

このインターフェースは、有効なラウンドトリップ時間とダウン値を使用して、ユーザーが使用しているネットワーク タイプを推定します。文字列(slow 2G、2G、3G、4G)を返すだけです。この値に応じて、ユーザーが 4G 未満の場合は、動画要素を画像に置き換えることができます。

if (navigator.connection.effectiveType) { ... }

エクスペリエンスは少し低下しますが、少なくとも低速接続でもサイトを使用できます。

オフスクリーン画像を遅延読み込みする

カルーセルやスライダー、非常に長いページでは、ユーザーがページ上ですぐに確認できなくても、多くの場合、画像が読み込まれます。

Lighthouse は、オフスクリーン画像の監査でこの動作を報告します。また、DevTools のネットワーク パネルでも確認できます。多くの画像が読み込まれているのに、ページに表示される画像が少ない場合は、代わりに画像を遅延読み込みすることを検討してください。

遅延読み込みはブラウザでネイティブにサポートされていないため、JavaScript を使用してこの機能を追加する必要があります。Lazysizes ライブラリを使用して、Oodle カバーに遅延読み込み動作を追加しました。

<!-- Import library -->
import lazysizes from 'lazysizes'  <!-- or -->
<script src="lazysizes.min.js"></script>

<!-- Use it -->

<img data-src="image.jpg" class="lazyload"/>
<img class="lazyload"
    data-sizes="auto"
    data-src="image2.jpg"
    data-srcset="image1.jpg 300w,
    image2.jpg 600w,
    image3.jpg 900w"/>

Lazysizes は、要素の可視性の変化をトラッキングするだけでなく、最適なユーザー エクスペリエンスを実現するためにビューの近くにある要素を事前にプリフェッチするため、スマートです。また、オプションで IntersectionObserver の統合も利用でき、可視性のルックアップが非常に効率的になります。

この変更により、画像はオンデマンドで取得されるようになりました。このトピックについて詳しくは、images.guide をご覧ください。これは非常に便利で包括的なリソースです。

ブラウザが重要なリソースを早期に配信できるようにする

インターネットでブラウザに送信されるすべてのバイトが同じ重要性を持つわけではなく、ブラウザはそれを認識します。多くのブラウザには、最初にフェッチする必要があるものを決定するヒューリスティクスがあります。画像やスクリプトの前に CSS を取得することもあります。

ページの作成者として、本当に重要な部分をブラウザに伝えることができるのは便利です。幸い、ここ数年、ブラウザ ベンダーは、link rel=preconnectpreloadprefetch などのリソース ヒントなど、この問題の解決に役立つ多くの機能を追加してきました。

ウェブ プラットフォームに導入されたこれらの機能は、ブラウザが適切なタイミングで適切なものを取得できるようにし、スクリプトを使用して行われるカスタム読み込みのロジックベースのアプローチよりも若干効率的です。

Lighthouse がこれらの機能の有効活用をどのようにサポートしているかを見てみましょう。

Lighthouse ではまず、コストのかかるラウンドトリップを複数の出発地に避けるように指示されています。

送信元への複数の往復を回避し、費用を削減
図 17. 費用のかかる複数の往復を避け、任意の出発地に移動する

Oodle アプリの場合は、実際に Google Fonts を多用しています。Google Font スタイルシートをページにドロップするたびに、最大 2 つのサブドメインが接続されます。Lighthouse は、この接続をウォームアップできれば、最初の接続時間を最大 300 ミリ秒短縮できると示しています。

link rel preconnect を利用することで、この接続レイテンシを効果的にマスクできます。

特に、フォントフェイスの CSS が googleapis.com でホストされ、フォント リソースが Gstatic でホストされている Google Fonts では、大きな影響を受ける可能性があります。この最適化を適用した結果、数百ミリ秒の短縮に成功しました。

Lighthouse では次に、キーリクエストがプリロードされていることが示されます。

プリロード鍵リクエスト
図 18. キーリクエストをプリロードする

<link rel=preload> は非常に強力で、現在のナビゲーションの一部としてリソースが必要であることをブラウザに通知し、できるだけ早くブラウザでフェッチを開始しようとします。

Lighthouse は、2 つのウェブフォントが読み込まれているため、重要なウェブフォント リソースをプリロードする必要があることを示しています。

ウェブフォントでプリロードを行うと、次のように表示されます。rel=preload を指定し、フォントタイプとともに as を渡します。次に、読み込むフォントタイプ(woff2 など)を指定します。

これはページに非常に大きな影響を与える可能性があります。

リソースのプリロードの影響
図 19. リソースのプリロードの影響

通常、link rel preload を使用せずに、ウェブフォントがページにとって重要である場合、ブラウザはまず HTML を取得し、CSS を解析し、その後でウェブフォントを取りにいきます。

link rel プリロードを使用すると、ブラウザで HTML が解析されるとすぐに、そのウェブフォントの取得をかなり早い段階で開始できます。アプリの場合、これにより、ウェブフォントを使用してテキストをレンダリングする時間を 1 秒短縮できました。

Google Fonts を使用してフォントをプリロードしようとすると、1 つ注意点があります。

スタイルシートのフォント フェイスに指定した Google Font URL は、フォントチームが定期的に更新するものです。これらの URL は期限切れになるか、定期的に更新される可能性があります。そのため、フォント読み込みを完全に制御したい場合は、ウェブフォントをセルフホストすることをおすすめします。これにより、リンク rel プリロードなどの機能にアクセスできるため、非常に便利です。

今回のケースでは、Google Web Fonts Helper というツールが、これらのウェブフォントの一部をオフラインにし、ローカルに設定するのに非常に役立ったと判断しました。ぜひお試しください。

重要なリソースの一部としてウェブフォントを使用している場合でも、JavaScript を使用している場合でも、ブラウザが重要なリソースをできるだけ早く配信できるようにしてください。

試験運用版: 優先度ヒント

今日は特別なことをお伝えします。リソースヒントやプリロードなどの機能に加えて、Google は試験運用版のブラウザの新しい機能を「優先ヒント」と呼ぶことに取り組んでいます。

最初に表示されるコンテンツの優先度を設定する
図 20.優先度に関するヒント

これは、リソースの重要度をブラウザにヒントとして伝えることができる新機能です。新しい属性 importance が公開され、値は low、high、auto です。

これにより、競合を減らすために、重要でないリソース(クリティカルでないスタイル、画像、フェッチ API 呼び出しなど)の優先度を下げることができます。ヘッダー画像など、より重要な要素の優先度を上げることもできます。

Oodle アプリの場合、この分析結果から、実際に最適化できる場所が 1 つ見つかりました。

最初に表示されるコンテンツの優先度を設定する
図 21. 最初に表示されるコンテンツの優先度を設定します

画像に遅延読み込みを追加する前は、ブラウザはすべてのドゥードルが含まれる画像カルーセルを表示し、カルーセルの一番最初に優先度の高いすべての画像をフェッチしていました。残念ながら、ユーザーにとって最も重要な画像はカルーセルの中央にありました。そこで、背景画像の重要度を非常に低く、前景画像の重要度を非常に高く設定しました。これにより、遅い 3G で 2 秒の差が生じ、画像の取得とレンダリングの速度が向上しました。良い経験になりました。

この機能は数週間以内に Canary に導入される予定です。

ウェブフォント読み込み戦略を準備する

タイポグラフィは優れたデザインの基本です。ウェブフォントを使用している場合は、テキストのレンダリングをブロックしないことが理想的です。また、テキストを非表示にすることは絶対に避けてください。

この問題は、Lighthouse のWeb フォント読み込み中の非表示テキストを回避する監査でハイライト表示されます。

Web フォント読み込み中のテキストの非表示を回避する
図 22. Web フォントが読み込まれている間、テキストが見えないようにしない

フォントフェイス ブロックを使用してウェブフォントを読み込む場合は、そのウェブフォントの取得に時間がかかる場合にどうするかをブラウザに決定させます。一部のブラウザでは、この処理が完了するまで最大 3 秒間待機してからシステム フォントに戻り、フォントがダウンロードされると、最終的にそのフォントに入れ替えます。

このテキストが表示されないという事態は避けようとしているので、ウェブフォントの表示に時間がかかりすぎていると、今週の定番の Doodle は表示できなかったでしょう。幸いなことに、font-display という新機能を使用すると、このプロセスをより細かく制御できます。

    @font-face {
      font-family: 'Montserrat';
      font-style: normal;
      font-display: swap;
      font-weight: 400;
      src: local('Montserrat Regular'), local('Montserrat-Regular'),
          /* Chrome 26+, Opera 23+, Firefox 39+ */
          url('montserrat-v12-latin-regular.woff2') format('woff2'),
            /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
          url('montserrat-v12-latin-regular.woff') format('woff');
    }

フォント表示を使用すると、ウェブフォントのスワップにかかる時間に基づいて、レンダリング方法やフォールバック方法を決定できます。

この例では、フォント表示の入れ替えを使用しています。Swap は、フォント フェースのブロック期間を 0 秒にし、スワップ期間を無限大にします。つまり、フォントが読み込みに時間がかかる場合、ブラウザは代替フォントですぐにテキストを描画します。フォント フェイスが利用可能になると、フォント フェイスが入れ替わります。

アプリの場合、これは非常に有用でした。初期段階で意味のあるテキストを表示し、準備が整ったらウェブフォントへと移行できたからです。

フォント表示の結果
図 23. フォント表示の結果

ウェブの大部分で使用されているウェブフォントを使用している場合は、適切なウェブフォント読み込み戦略を用意してください。

フォントの読み込みエクスペリエンスを最適化するために使用できるウェブ プラットフォームの機能はたくさんありますが、Zach Leatherman の ウェブフォント レシピ リポジトリもぜひご覧ください。

レンダリングをブロックするスクリプトを削減する

ダウンロード チェーンの早い段階でプッシュできるアプリの部分もあり、少なくとも少し前に基本的なユーザー エクスペリエンスを提供できます。

Lighthouse のタイムライン ストリップでは、すべてのリソースが読み込まれている最初の数秒間は、ユーザーにコンテンツが表示されないことがわかります。

レンダリングを妨げるスタイルシートの機会を減らす
図 24. レンダリングを妨げるスタイルシートの機会を減らす

外部スタイルシートのダウンロードと処理により、レンダリング プロセスが進まない。

いくつかのスタイルを少し早く提供することで、クリティカル レンダリング パスを最適化してみることができます。

この最初のレンダリングを担当するスタイルを抽出して HTML にインライン化すると、ブラウザは外部スタイルシートの到着を待たずにすぐにレンダリングできます。

この例では、Critical という NPM モジュールを使用して、ビルドステップ中に重要なコンテンツを index.html にインライン化しました。

このモジュールは、ほとんどの作業を自動化してくれますが、さまざまなルートでスムーズに動作させるには、少し工夫が必要です。

注意を払わない場合や、サイト構造が非常に複雑な場合、最初からアプリシェル アーキテクチャを計画していないと、このタイプのパターンを導入するのは非常に困難になる可能性があります。

そのため、早い段階でパフォーマンスを考慮することが重要です。最初からパフォーマンスを考慮して設計しないと、後で問題に遭遇する可能性が高くなります。

最終的に、リスクを冒した甲斐があり、うまく機能し、アプリはコンテンツの配信を大幅に早め、最初の意味のあるペイント時間を大幅に改善しました。

結果

以上、サイトに適用したパフォーマンス最適化の長いリストでした。結果を見てみましょう。以下は、3G ネットワーク上の中程度のモバイル デバイスで、最適化前と最適化後のアプリの読み込み時間です。

Lighthouse のパフォーマンス スコアは 23 から 91 に上昇しました。速度の面ではかなりの進歩です。すべての変更は、Lighthouse レポートを継続的に確認し、それに沿って行われました。すべての改善が技術的にどのように実装されたかを確認したい場合は、リポジトリ、特にそこに配置された PR をご覧ください。

予測パフォーマンス - データドリブンのユーザー エクスペリエンス

Google は、機械学習が多くの分野で将来の大きな可能性を秘めていると考えています。今後、より多くのテストを促進したいと考えているアイデアのひとつは、実際のデータが Google が作成するユーザー エクスペリエンスを本当にガイドできるということです。

現在、Google は、ユーザーが望むものや必要とするものを、つまりプリフェッチ、プリロード、プリキャッシュに値するものを、恣意的に判断しています。推測が正しければ、少量のリソースを優先できますが、ウェブサイト全体にスケーリングするのは非常に困難です。

実は、最適化に役立つデータはすでに利用可能です。Google アナリティクス Reporting API を使用すると、サイト上の任意の URL の次に多いページと離脱率を確認できるため、優先すべきリソースを判断できます。

これを優れた確率モデルと組み合わせると、コンテンツを積極的に過剰にプリフェッチして、ユーザーのデータを無駄にすることを避けられます。このようなモデルを実装するには、Google アナリティクスのデータを利用し、機械学習とマルコフ連鎖ニューラル ネットワークなどのモデルを使用します。

ウェブアプリ用データドリブン バンドル
図 25.ウェブアプリ用のデータドリブン バンドル

このテストを容易に実施できるように、Guess.js という新しいイニシアチブを発表いたします。

Guess.js
図 26. Guess.js

Guess.js は、ウェブ向けのデータドリブンなユーザー エクスペリエンスに焦点を当てたプロジェクトです。このデータが、ウェブ パフォーマンスの向上にとどまらず、さらにはデータの活用を検討していくきっかけとなることを願っています。すべてオープンソースであり、現在 GitHub で入手できます。これは、Minko Gechev、Gatsby の Kyle Matthews、Katie Hempenius など、オープンソース コミュニティと協力して構築されました。

Guess.js を試して、ご意見をお聞かせください。

概要

スコアと指標はウェブの速度を改善するうえで役立ちますが、あくまで手段であり、目標そのものではありません。

外出先でページの読み込みが遅いと感じたことがある人は多いと思いますが、この機能により、読み込みが非常に速く、より快適なエクスペリエンスをユーザーに提供できるようになりました。

パフォーマンスの向上は、長い道のりです。小さな変化を積み重ねることで、大きな成果につながります。適切な最適化ツールを使用し、Lighthouse レポートを常に確認することで、ユーザーに優れた包括的なエクスペリエンスを提供できます。

特別な感謝を捧げます。Ward Peeters、Minko Gechev、Kyle Mathews、Katie Hempenius、Dom Farolino、Yoav Weiss、Susie Lu、Yusuke Utsunomiya、Tom Ankers、Lighthouse、Google Doodles に感謝いたします。