blog

ブラウザのパフォーマンス - 遅延について知っておくべきこと

つまり、ブラウザカーネルの UI スレッドが 50ms 以上スタックすると、スタック例外がスローされます。 これにより、アクションに応答する時間が50ミリ秒未満になるため、アプリケーションは50ミリ秒...

Jul 19, 2020 · 5 min. read
シェア

ラグとは

このため、ブラウザのUIスレッドがブロックされると、ユーザーはラグを感じると考えられ、この値を50msに設定しています。 つまり、ブラウザカーネルのUIスレッドが50ms以上ブロックされると、ラグ例外として記録されます。

ユーザーの感覚からすると、遅延のしきい値は100msと感じられます。50msに設定されている理由は、ブラウザのイベントキューイング機構が、1つのタスクに50ms以上かかると、次にユーザー入力が発生したときに、ブラウザはまず、100ms以内にユーザーの操作に応答できるようにするために、前のタスクが次のタスクの実行を完了するまで待たなければならないと判断するためです100ms以内にユーザーの操作に応答するためには、ブラウザがその操作に応答できる残り時間は50ms以下なので、アプリケーションは50msごとにメインスレッドに制御を戻さなければなりません。

アイドルタスクがラグにどのように影響するかは、下のグラフをご覧ください:

なぜ100ミリ秒なのですか?

ユーザーがパフォーマンスの遅れをどのように受け止めているかについての分析です。

  • 0~16ミリ秒

    ユーザーは動きを追跡するのが得意で、アニメーションが滑らかでないと嫌がります。毎秒60フレームがレンダリングされると、すぐにアニメーションの滑らかさを感じることができます。一方、このアプリは1フレームを生成するのに約10ミリ秒かかります。

  • 0~100ms

    ユーザーの操作に対応するこの時間帯であれば、ユーザーは非常にタイムリーな結果だと感じるでしょうし、時間が長くなれば、ユーザーはタイムラグを感じるでしょう。

  • 100~1000ミリ秒

    この間、ページの読み込みやビューの変更など、ウェブ上のほとんどのユーザーにとってタスクは自然な連続進行です。

  • 1000ミリ秒以上

    1000ミリ秒以上経過すると、ユーザーはタスクの実行に集中できなくなります。

  • ミリ秒以上 10,000ミリ秒以上

    ユーザーはフラストレーションを感じ、タスクを放棄する可能性が高くなります。後で戻ってくるかもしれないし、戻ってこないかもしれません。

ラグに関する問題の可能性

  • 対話可能時間の遅延の原因

    ページがロードされると、ロングタスクがメインスレッドを占有し、ページがすでにレンダリングされているにもかかわらず、ユーザーがページとやりとりするのを妨げます。

  • 入力応答遅延

    重要なユーザーインタラクションイベントがロングタスクの後にスケジュールされるため、ユーザーエクスペリエンスが低下し、予測不可能な問題が発生します。

  • イベント処理の遅延

    入力の遅延と似ていますが、ここではonloadのようなイベントコールバックの処理の遅延を指します。

  • アニメーションとスクロールの質が悪い

    アニメーションやスクロールの中には、タイプセットとメインスレッドの協力が必要なものがあり、メインスレッドがロングタスクによってブロックされると、アニメーションやスクロールのスムーズさに影響が出ます。

ブラウザ側でラグを表示する方法

Chromeのパフォーマンスで確認できます。赤はタスクが50ms以上であることを意味します。

Long tasks

ご存知のように、jsはシングルスレッドです。jsはイベントループを使ってイベントを処理します。ユーザーが入力すると、対応するイベントがトリガーされ、ブラウザは対応するタスクをイベントループのキューに入れます。jsはシングルスレッドで、イベントループのキューにあるタスクを1つずつ処理します。一つのタスクに特に時間がかかる場合、キュー内の他のタスクはブロックされます。同時に、jsスレッドとuiレンダリングスレッドは相互に排他的です。つまり、jsが実行中であれば、uiレンダリングはブロックされます。この時点で、ユーザーはラグやちらつきを経験することになり、これは現在のウェブページにおける悪いユーザーエクスペリエンスの主な原因となります。LonagタスクAPIは、タスクが50msを超えた場合、潜在的に問題があるとみなし、アプリケーション開発者にこれらのタスクを表示します。50msが選ばれたのは、100ms以内にユーザが応答するというRAILモデルの要件を満たすためです。

レポートの作り方

Long Task API使用します。

ユーザーがラグを感じないように最適化する方法

  • リクエストアニメーションフレーム

    このAPIが行うのは、入力されたコールバックを受け取り、次のフレームの開始時に即座に実行することです。このAPIを使うことで、あるタスクを優先度の高いタスクとして実行させることができ、ユーザーにとってUI関連は優先度の高いタスクです。

  • リクエストアイドルコールバック

    これは、ブラウザのアイドル時間中に呼び出される関数をキューに入れることで機能します。これにより開発者は、アニメーションや入力応答などの遅延したクリティカルなイベントに影響を与えることなく、メインイベントループのバックグラウンドで優先度の低い作業を行うことができます。通常、関数は先入れ先出しの順番で実行されますが、コールバック関数に実行のタイムアウトが指定されている場合は、タイムアウト前に関数を実行するために実行の順番を乱すことができます。

    この API は、優先順位の低いタスクが優先順位の高いタスクやブラウザの UI レンダリングのためにリソースを利用できるようにするもので、これらのタスクがフレーム内で時間切れになった場合、優先順位の低いタスクは次の利用可能なフレームにスケジューリングされます。

  • cssのレイアウト操作をjsで減らし、減らします。

    たとえば、幅や高さなどを変更します。要素のスタイルを取得すると、レイアウトもトリガーされます。transform を使用して要件を満たすことができる場合は、position/width/height を使用してアニメートしないでください。

  • DOM構造の縮小

    DOM の構造が複雑になると、より多くの要素を再描画する必要があります。これは、アニメーションのシナリオや、scroll/mousemove イベントをリッスンする必要がある場合に特に当てはまります。さらに、flex を使用すると float を使用して再描画するよりも有利になります。詳しくは を参照してください。

    Reactの新しいFiberアーキテクチャ。これは主に、jsコードの実行中に長いタスクが発生する問題を解決するためのものです。リコンシリエーションは、Reactが仮想ドムツリーを差分し、どの部分を更新する必要があるかを決定するために使用するアルゴリズムです。リコンシリエーションは異なるレンダリングプラットフォームで共有することができ、reactはサブツリーの更新を一度計算し、すぐに再レンダリングするように設計されています。このため、タスクが長くなりがちです。

Fiber アーキテクチャでは、requestAnimationFrame と requestIdleCallback を使用してこの問題を解決します。 Fiber の中核は、長いタスクを優先順位の異なる複数の短いタスクに分割し、これらのタスクの実行をスケジュールして、重要なコンテンツが最初にレンダリングされ、GUI レンダリング スレッドがブロックされないようにすることです。これにより、長いタスクの問題が解決されます。react の Fiber アーキテクチャの最新バージョン 17 では、独自の requestAnimationFrame 関数と requestIdleCallback 関数を実装し、よりきめ細かいレベルを実現しています。

Read next

[Flutter】Flutterで最初の10個の商用アプリを作って学んだこと

Flutterプロジェクトで過去24ヶ月間に最初の10個のビジネスアプリを作った後、私はそれらを作った後に学んだ教訓を共有します。\nこの記事を読めば、次のことがわかります。\nFlutterを選んだ理由と、Flutterが予算と安定性に与える影響とは?\nF

Jul 18, 2020 · 9 min read