scheduler.yield() の紹介: INP を最適化するための Chrome の最新 API
公開: 2023-09-152023 年に Google がレスポンシブネスを重視していることは疑いの余地がありません。
これまでのところ、彼らは次のことを行っています。
- インタラクションを次のペイントに実験から保留に移動しました。
- 2024 年 3 月に、INP が応答性の新しいコア Web Vital メトリクスとして First Input Delay に代わることを発表しました。
- Search Console で INP の問題にフラグを立て、良好な応答性の基準を満たしていない Web サイトにメールを送信し始めました。
さて、Chrome チームは現在、新しいスケジューラー API であるスケジューラー.yield()のオリジン トライアルを実行中であると発表しました。
scheduler.yield() は、開発者がメインスレッドに制御を戻すためのより簡単で優れた方法を提供することで、開発者がサイトの応答性を向上させるのに役立つことが期待されています。
新しい API とそれを Web サイトで試す方法の詳細については、以下をお読みください。
長いタスクとメインスレッドの簡単な要約
長いタスクとメインスレッドがどのようなものかをよく理解している場合は、この部分をスキップしても構いません。 そうでない場合は、この簡単な要約を読むことをお勧めします。これは、scheduler.yield()とその実装方法を理解するための基礎です。
ブラウザが作業として実行するすべてのことはタスクとみなされます。 これには、レンダリング、HTML と CSS の解析、作成した JavaScript コードの実行、および直接制御できないその他の処理が含まれます。
メイン スレッドは、ブラウザがほとんどの作業を行う場所です。
残念ながら、メインスレッドは一度に 1 つのタスクしか処理できません。 また、タスクの実行に 50 ミリ秒以上かかる場合、それは長いタスクとみなされます。
長いタスクが発生すると、ブラウザは完了するまでに必要なだけタスクを実行します。 終了すると、制御がメイン スレッドに戻され、ブラウザがキュー内の次のタスクを処理できるようになります。
長いタスクは、ユーザー入力に対するブラウザーの応答能力を遅らせるため、ページの応答性低下の主な原因となります。 さらに、実行から完了までのモデルを備えた JavaScript が、メインスレッドをブロックする主な原因となります。
そのため、これはレンダリング ブロック リソースとみなされます。ブラウザーがこのリソースを検出すると、他のことを行う前にダウンロード、解析、および実行する必要があります。
幸いなことに、コードがブラウザーでタスクを開始したからといって、そのタスクが終了するまで制御がメインスレッドに戻るまで待つ必要があるわけではありません。
タスク内で明示的に譲歩することで、長いタスクを分割できます。
簡単に言うと、タスク譲与により、ブラウザーが 1 つのタスクに夢中になりすぎて、他の重要なタスクやユーザー インタラクションへの応答を見逃したり遅延したりすることがなくなります。
残念ながら、現在の収益戦略は完璧ではありません…
scheduler.yield() を使用する理由: 現在の利回り戦略の問題
メインスレッドに従うというのは新しい概念ではありません。 開発者は長い間、さまざまな生成戦略を使用して長いタスクを分割してきました。
1.setTimeout()
setTimeout() を使用すると、指定した遅延の後、または定期的な間隔でタスクを実行するようにスケジュールできます。 これにより、タイムアウトを 0 に指定した場合でも、コールバックの実行が別のタスクに延期されます。この方法は、複数の関数を次々に実行する必要がある場合に効果的です。
欠点:精度は保証されません。 キュー内の他のタスクにより、コールバックは指定された遅延の後に正確に実行されない可能性があります。 また、膨大なデータセットをループで処理している場合、特に数百万のエントリがある場合、タスクに時間がかかる可能性があります。
2. requestIdleCallback()
requestIdleCallback() を使用すると、ブラウザーのアイドル期間中に実行されるタスクをスケジュールできます。 ユーザー エクスペリエンスに影響を与えることなく、緊急ではないタスクを実行する場合に便利です。
欠点: requestIdleCallback() は、可能な限り低い優先順位でタスクをスケジュールします。つまり、メイン スレッドが混雑している場合、スケジュールされたタスクが実行されない可能性があります。
3. isInputPending()
isInputPending() はいつでも実行して、ユーザーがページ上の要素を操作しようとしているかどうかを確認できます。 該当する場合、関数はtrueを返します。 そうでない場合は、 falseを返します。
実行すべきタスクはたくさんあるが、ユーザーの対話を中断したくないと想像してください。 isInputPending() 関数とyieldToMain()関数を使用すると、ユーザーがページを操作するときに入力が遅れないようにすることができます。
欠点: isInputPending() は、ユーザー入力直後に常に true を返すとは限りません。 これは、オペレーティング システムがブラウザに対話が発生したことを伝えるまでに時間がかかるためです。 これは、他のコードがすでに実行を開始している可能性があることを意味します。
これらは、メインスレッドに戻る一般的な方法の一部です。 ご覧のとおり、それぞれに独自の欠点があります。
しかし、最も重大な欠点は次のとおりです。
後続のタスクで実行するコードを延期することでメインスレッドに譲ると、そのコードはタスクキューの最後に追加されます。
なぜそれが問題になるのでしょうか?
それは 3 つの答えです。
- ロジック エラーの可能性の増加:遅延コードはタスク キューの最後に配置されるため、ブラウザは遅延タスクに戻る前に他のタスクを実行する可能性があります。 これは関数の実行順序に影響を与え、論理エラーや予期しない動作を引き起こす可能性があります。
- 実行の遅延: キュー内に多くのタスクがある場合、ブラウザーが遅延コードに到達して実行するまでにかなりの時間がかかる可能性があります。
- 予測不可能性:遅延タスクがいつ実行されるかを正確に予測することは、すでにキューに入っているタスクの数と性質に依存するため、困難です。 この予測不可能性により、デバッグとパフォーマンスの最適化が困難になる可能性があります。
要約すると、メインスレッドに譲歩する現在の戦略を使用すると、応答性の高いユーザー インターフェイスを維持するのに役立ちますが、コードをタイムリーかつ秩序正しく実行することを保証する上で課題が生じる可能性もあります。
scheduler.yield() の紹介
Chrome が Scheduler.yield() のオリジン トライアルを実行していることに興奮しているのは、これが他の生成戦略の欠点をすべて解決するスケジューラー API であるためです。
それに加えて、開発者と所有者の両方が残りのコードをシームレスに実行しながら、応答性の高い Web サイトと良好な INP スコアを達成できるソリューションです。
では、 scheduler.yield()についての誇大宣伝は何でしょうか?
まず、 scheduler.yield()は専用の yield 関数です。 たとえば、setTimeout() は長いタスクを分割してメインスレッドに渡すために使用されますが、これはデフォルトのオプションというよりは関数の副作用です。
次に、 scheduler.yield() は残りの作業をキューの先頭に送信します。 これは、譲歩した後すぐに再開したい作業が、他のソースからのタスクに後回しにされないことを意味します。
簡単に言えば:
scheduler.yield()は両方の長所を提供します。サイトの応答性と INP スコアを向上させるために譲歩することができ、譲歩後に完了させたい作業が遅れないようにすることができます。
新しいスケジューラ API を試す方法
Chrome 115 以降では、scheduler.yield を自分でテストできるようになりました。
新しい API を試すには、Google の指示に従ってください。
- ローカルでスケジューラ.yield を試したい場合は、Chrome のアドレス バーにchrome://flags と入力し、[実験的な Web プラットフォームの機能] セクションのドロップダウンから [有効にする] を選択します。 これにより、scheduler.yield (およびその他の実験的な機能) が Chrome のインスタンスでのみ利用可能になります。
- 公的にアクセス可能なオリジンで実際の Chromium ユーザーに対してスケジューラ.yield を有効にしたい場合は、scheduler.yield オリジン トライアルにサインアップする必要があります。 これにより、提案された機能を一定期間安全に試すことができ、Chrome チームはそれらの機能が現場でどのように使用されているかについて貴重な洞察を得ることができます。 オリジントライアルの仕組みの詳細については、このガイドをお読みください。
テストしたら、改善方法についてフィードバックを提供することもできます。
安全な検査!
NitroPack がメインスレッドのブロック解除にどのように役立つか
長いタスクを小さな塊に分割することは、ユーザーに軽快なエクスペリエンスを提供するために不可欠です。
しかし、重い JavaScript の一部を事前に最適化できた方が良いと思いませんか?
そこでニトロパックの登場です。
NitroPack は、 35 を超える高度な Web パフォーマンス機能により、世界中の 180,000 以上の Web サイトが優れたユーザー エクスペリエンス、コア Web バイタル、コンバージョン率を達成できるように支援します。
NitroPack の最も重要な利点の 1 つは、JavaScript の実行を処理する方法です。
NitroPack をインストールすると、当社のサービスは、ユーザーの操作が検出されるまで、重要ではないリソースの読み込みを遅らせます。
さらに、独自のリソース読み込みメカニズムのおかげで、NitroPack はリソースがメインスレッドに供給される方法を再調整できます。 これは、タスクをメインスレッドからオフロードすることで最新の CPU のマルチコアの性質を利用するために行われます。
こうすることで、メインスレッドがブロックされていない状態を維持し、ユーザーとの対話を処理できることを保証できます。