Skip to content

Commit

Permalink
perf: timer optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonocasey committed Jul 29, 2019
1 parent 0b91a71 commit 1414906
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 19 deletions.
15 changes: 15 additions & 0 deletions src/js/control-bar/progress-control/play-progress-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import Component from '../../component.js';
import {IS_IOS, IS_ANDROID} from '../../utils/browser.js';
import * as Fn from '../../utils/fn.js';

import './time-tooltip';

Expand All @@ -14,6 +15,20 @@ import './time-tooltip';
*/
class PlayProgressBar extends Component {

/**
* Creates an instance of this class.
*
* @param {Player} player
* The {@link Player} that this class should be attached to.
*
* @param {Object} [options]
* The key/value store of player options.
*/
constructor(player, options) {
super(player, options);
this.update = Fn.throttle(Fn.bind(this, this.update), 25);
}

/**
* Create the the DOM element for this class.
*
Expand Down
69 changes: 52 additions & 17 deletions src/js/control-bar/progress-control/seek-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,19 @@ class SeekBar extends Slider {
setEventHandlers_() {
this.update = Fn.throttle(Fn.bind(this, this.update), UPDATE_REFRESH_INTERVAL);

this.on(this.player_, 'timeupdate', this.update);
this.on(this.player_, 'ended', this.handleEnded);
this.on(this.player_, 'durationchange', this.update);
if (this.player_.liveTracker) {
this.on(this.player_.liveTracker, 'liveedgechange', this.update);
}

// when playing, let's ensure we smoothly update the play progress bar
// via an interval
this.updateInterval = null;

this.on(this.player_, ['playing'], this.enableInterval_);

this.on(this.player_, ['ended', 'pause', 'waiting'], this.disableInterval_);
this.player_.ready(() => {
this.on(this.player_, ['useractive'], this.userActive_);
this.on(this.player_, ['userinactive'], this.userInactive_);
if (this.player_.userActive()) {
this.userActive_();
} else {
this.userInactive_();
}
});

// we don't need to update the play progress if the document is hidden,
// also, this causes the CPU to spike and eventually crash the page on IE11.
Expand All @@ -76,6 +75,38 @@ class SeekBar extends Slider {
}
}

userActive_() {
if (this.listenersEnabled_) {
return;
}
this.listenersEnabled_ = true;
this.on(this.player_, ['playing'], this.enableInterval_);
this.on(this.player_, ['ended', 'pause', 'waiting'], this.disableInterval_);
this.on(this.player_, 'timeupdate', this.update);
this.on(this.player_, 'ended', this.handleEnded);
this.on(this.player_, 'durationchange', this.update);
if (this.player_.liveTracker) {
this.on(this.player_.liveTracker, 'liveedgechange', this.update);
}
this.enableInterval_();
}

userInactive_() {
if (!this.listenersEnabled_) {
return;
}
this.listenersEnabled_ = false;
this.off(this.player_, ['playing'], this.enableInterval_);
this.off(this.player_, ['ended', 'pause', 'waiting'], this.disableInterval_);
this.off(this.player_, 'timeupdate', this.update);
this.off(this.player_, 'ended', this.handleEnded);
this.off(this.player_, 'durationchange', this.update);
if (this.player_.liveTracker) {
this.off(this.player_.liveTracker, 'liveedgechange', this.update);
}
this.disableInterval_();

}
toggleVisibility_(e) {
if (document.hidden) {
this.disableInterval_(e);
Expand All @@ -88,6 +119,9 @@ class SeekBar extends Slider {
}

enableInterval_() {
if (this.updateInterval) {
return;
}
this.clearInterval(this.updateInterval);

this.updateInterval = this.setInterval(() =>{
Expand All @@ -96,11 +130,18 @@ class SeekBar extends Slider {
}

disableInterval_(e) {
if (this.player_.liveTracker && this.player_.liveTracker.isLive() && e.type !== 'ended') {
if (!this.updateInterval) {
return;
}
const isLive = this.player_.liveTracker && this.player_.liveTracker.isLive();

// live interval continues to update on events not listed
if (isLive && (e.type !== 'ended' || e.type === 'userinactive')) {
return;
}

this.clearInterval(this.updateInterval);
this.updateInterval = null;
}

/**
Expand Down Expand Up @@ -169,12 +210,6 @@ class SeekBar extends Slider {
* The current percent at a number from 0-1
*/
update(event) {
// if the offsetParent is null, then this element is hidden, in which case
// we don't need to update it.
if (this.el().offsetParent === null) {
return;
}

const percent = super.update();

this.update_(this.getCurrentTime_(), percent);
Expand Down
17 changes: 16 additions & 1 deletion src/js/control-bar/progress-control/time-tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import Component from '../../component';
import * as Dom from '../../utils/dom.js';
import formatTime from '../../utils/format-time.js';
import * as Fn from '../../utils/fn.js';

/**
* Time tooltips display a time above the progress bar.
Expand All @@ -12,6 +13,20 @@ import formatTime from '../../utils/format-time.js';
*/
class TimeTooltip extends Component {

/**
* Creates an instance of this class.
*
* @param {Player} player
* The {@link Player} that this class should be attached to.
*
* @param {Object} [options]
* The key/value store of player options.
*/
constructor(player, options) {
super(player, options);
this.update = Fn.throttle(Fn.bind(this, this.update), 25);
}

/**
* Create the time tooltip DOM element
*
Expand Down Expand Up @@ -88,7 +103,7 @@ class TimeTooltip extends Component {
/**
* Write the time to the tooltip DOM element.
*
* @param {String} content
* @param {string} content
* The formatted time for the tooltip.
*/
write(content) {
Expand Down
28 changes: 27 additions & 1 deletion src/js/control-bar/time-controls/time-display.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,33 @@ class TimeDisplay extends Component {
constructor(player, options) {
super(player, options);
this.throttledUpdateContent = throttle(bind(this, this.updateContent), 25);
this.on(player, 'timeupdate', this.throttledUpdateContent);
this.enableUpdateContent_ = bind(this, this.enableUpdateContent_);
this.disableUpdateContent_ = bind(this, this.disableUpdateContent_);
this.player.ready(() => {
this.on(player, 'useractive', this.enableUpdateContent_);
this.on(player, 'userinactive', this.disableUpdateContent_);
if (this.player.userActive()) {
this.enableUpdateContent_();
} else {
this.disableUpdateContent_();
}
});
}

enableUpdateContent_() {
if (this.updateContentEnabled_) {
return;
}
this.updateContentEnabled_ = true;
this.on(this.player_, 'timeupdate', this.throttledUpdateContent);
}

disableUpdateContent_() {
if (!this.updateContentEnabled_) {
return;
}
this.updateContentEnabled_ = false;
this.off(this.player_, 'timeupdate', this.throttledUpdateContent);
}

/**
Expand Down

0 comments on commit 1414906

Please sign in to comment.