背景タブでdocument.titleを更新する

ユーザーの満足度を高め、開いているタブを知らせるためにdocument.titleに価格を表示するチケットサイトがあるとします(変更されるかどうかわからないため)逆に、出発地/到着地、日付、お気に入りの運送業者など、および価格は、さまざまな組み合わせでほぼ常に異なります)。 同時に、バージョン56以降、Chromeにはバックグラウンドタブをブロックするポリシーがあります。 この機能にとってこれはどういう意味ですか?



ドキュメントによると、rAF(requestAnimationFrame)は通常1秒あたり60回呼び出されます。 リフレッシュレートが高い画面では、この値も高くなります(目では気づかないかもしれませんが)。



さらに、タブがバックグラウンドでアクティブでない場合、頻度が低下する可能性があると書かれています。これは、以下で説明します。



実験してみましょう。 requestAnimationFrameスポイラーの下のコードでは、タイトルは最も簡単な方法で更新されます。



requestAnimationFrameページ
<!DOCTYPE> <html> <head> <script> requestAnimationFrame(function() { document.title += ' RAF' }); </script> <title>tab</title> </head> <body>tab</body> </html>
      
      







クロムの結果は次のとおりです。



クロム




はい、そうです。 他のブラウザが何をするのか見てみましょう:



IE11
設定を行わず、スクリプトをローカルサイトで実行できないように、 http-serverコマンドとlt -p 8080コマンドを組み合わせて使用​​します。







* Edgeは同様に機能します



サファリ




Firefox


e10sは電解です



結果-FirefoxのみがバックグラウンドタブでrAFを実行します。 IE11でもバックグラウンドでrAFを実行しないのは驚くべきことですが、ドキュメントによると、ChromeはページがバックグラウンドにあるときにrequestAnimationFrame()を呼び出しません。 この動作は2011年から導入されています。 2011年以降、カール! バックグラウンドで音楽が再生されても( <audio src="sound.mp3" autoplay></audio>



など)、バックグラウンドで、あらゆる条件下で、ブラウザ以外でrAF FF、実行されません。



したがって、最初の質問「タイトルに価格を表示する方法」に答えると、答えは非常に簡単です。コンポーネントが表示された時点ではなく、APIからデータを受信した時点で表示します。 2番目の解決策は、APIからデータを返すときにページをアニメーション化するために使用される関数から削除することです(大画面ローダーを全画面で適切に削除します)、初期化関数。 残念なことに、何らかの理由でそのような関数が複数あるため、このオプションには大きな順列が必要であり、それを放棄することにしました。 ちなみに、setTimeout / setIntervalは正しく実行され、それらを通して問題の3番目の解決策が可能です。



このストーリーでは、終了して閉じることができます。次に、WebKitのrequestAnimationFrameソースコードを使用して、実際に何が起こるかを見てみましょう。



 int Document::requestAnimationFrame(Ref<RequestAnimationFrameCallback>&& callback) { if (!m_scriptedAnimationController) { #if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR) m_scriptedAnimationController = ScriptedAnimationController::create(*this, page() ? page()->chrome().displayID() : 0); #else m_scriptedAnimationController = ScriptedAnimationController::create(*this, 0); #endif // It's possible that the Page may have suspended scripted animations before // we were created. We need to make sure that we don't start up the animation // controller on a background tab, for example. if (!page() || page()->scriptedAnimationsSuspended()) m_scriptedAnimationController->suspend(); if (page() && page()->isLowPowerModeEnabled()) m_scriptedAnimationController->addThrottlingReason(ScriptedAnimationController::ThrottlingReason::LowPowerMode); if (!topOrigin().canAccess(securityOrigin()) && !hasHadUserInteraction()) m_scriptedAnimationController->addThrottlingReason(ScriptedAnimationController::ThrottlingReason::NonInteractedCrossOriginFrame); } return m_scriptedAnimationController->registerCallback(WTFMove(callback)); }
      
      





最初のifはかなり単純で、さらにsuspendScriptedAnimationssetIsVisibleInternalについてです。



2番目のif( isLowPowerModeEnabled関数の値)では、各OSは異なるソースから取得されます。 iOSでは、おそらく_didReceiveLowPowerModeChangeから取得されます



3番目のifは最も興味深いものです。 topOriginは、単に最上位のSecurityOriginドキュメントです。 メソッド自体はここにあります。このメソッドのコメントには、メソッド内で何が起こっているかについて十分に詳しく説明されています。 このメソッドは、 起源が異なる2つのスクリプトが互いに通信できる場合(読み取りまたは書き込み用)にtrueを返します。 同時に、ユーザーはNonInteractedCrossOriginFrameで操作する余地があります。



したがって、webkitブラウザーは、3つのifのいずれかを入力するたびにrAFロックを受け取ります。



Firefoxに戻ります。 ページタイトルを次のように変更する元の関数を変換します。



各アニメーションフレームのタイトルを変更します
  requestAnimationFrame(function handler() { document.title += 'R' requestAnimationFrame(handler); });
      
      







結果




ご覧のとおり、 Firefox / Geckoでは 、すべてがWebkitとは少し異なります。 request_animation_frame実装を見つけると、次のことに気付くでしょう。



  1. // TODO:ドキュメントが表示されているときにのみアニメーションをオンにする必要があります。つまり、いつかは他のブラウザの動作に対応するため、現在何が起こっているかに特に集中できません。
  2. is_faking_animation_framesがあるので、Geckoの人たちは偽のアニメーションがたくさんある場合は、FakeRequestAnimationFrameCallbackを投げます。


誰がかっこいいのかさえ知りません。



良いリンク:






All Articles