From ef0801cee0d630d8ac42f25ed42662bd471806e1 Mon Sep 17 00:00:00 2001 From: DispatchCommit Date: Tue, 28 Apr 2020 05:02:57 -0700 Subject: [PATCH] Add RAF flag Fixes: https://github.com/videojs/video.js/issues/5937 Issue originally found and explained by meikidd, see: https://github.com/videojs/video.js/issues/5937#issuecomment-539442030 Add requestAnimationFrame (RAF) flag to prevent RAF calls from stacking in background This component's `update` method is called via a `setInterval` which runs when a tab is in the background. Since `update` is continuously called, RAF calls are made each tick, but RAF does not fire in the background. RAF calls stack while tab is in the background and will fire immediately when tab regains focus. This causes a potentially huge number of RAF calls to attempt to immediately execute when tab regains focus, which can potentially lock up a tab entirely until all queued RAF's finish firing. To prevent this issue, we can use a variable to track when an RAF call is made, and prevent additional calls from being made until the last queued RAF function executes. --- .../progress-control/load-progress-bar.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/js/control-bar/progress-control/load-progress-bar.js b/src/js/control-bar/progress-control/load-progress-bar.js index 59e357739d..ccef1fbf25 100644 --- a/src/js/control-bar/progress-control/load-progress-bar.js +++ b/src/js/control-bar/progress-control/load-progress-bar.js @@ -28,6 +28,7 @@ class LoadProgressBar extends Component { constructor(player, options) { super(player, options); this.partEls_ = []; + this.needsRequestAnimationFrame = true; this.on(player, 'progress', this.update); } @@ -72,6 +73,11 @@ class LoadProgressBar extends Component { * @listens Player#progress */ update(event) { + // Prevent multiple RAF's from being called when tab is in background since setInterval runs in background, but RAF does not. + if (!this.needsRequestAnimationFrame) { + return; + } + this.requestAnimationFrame(() => { const liveTracker = this.player_.liveTracker; const buffered = this.player_.buffered(); @@ -117,7 +123,13 @@ class LoadProgressBar extends Component { this.el_.removeChild(children[i - 1]); } children.length = buffered.length; + + // Allow additional RAF's after update has completed + this.needsRequestAnimationFrame = true; }); + + // Prevent additional RAF's from being called + this.needsRequestAnimationFrame = false; } }