mirror of
https://github.com/videojs/video.js.git
synced 2025-02-02 11:34:50 +02:00
perf: Another 5ms of startup time improvements (#6145)
This commit is contained in:
parent
f324d1f23c
commit
22782b8425
50
package-lock.json
generated
50
package-lock.json
generated
@ -626,6 +626,15 @@
|
||||
"@babel/helper-plugin-utils": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-object-assign": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.2.0.tgz",
|
||||
"integrity": "sha512-nmE55cZBPFgUktbF2OuoZgPRadfxosLOpSgzEPYotKSls9J4pEPcembi8r78RU37Rph6UApCpNmsQA4QMWK9Ng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-object-super": {
|
||||
"version": "7.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz",
|
||||
@ -5168,8 +5177,7 @@
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
@ -5190,14 +5198,12 @@
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@ -5212,20 +5218,17 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@ -5342,8 +5345,7 @@
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@ -5355,7 +5357,6 @@
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@ -5370,7 +5371,6 @@
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@ -5378,14 +5378,12 @@
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
@ -5404,7 +5402,6 @@
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@ -5485,8 +5482,7 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@ -5498,7 +5494,6 @@
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -5584,8 +5579,7 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
@ -5621,7 +5615,6 @@
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@ -5641,7 +5634,6 @@
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
@ -5685,14 +5677,12 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -93,6 +93,7 @@
|
||||
"@babel/cli": "^7.4.4",
|
||||
"@babel/core": "^7.4.5",
|
||||
"@babel/node": "^7.4.5",
|
||||
"@babel/plugin-transform-object-assign": "^7.2.0",
|
||||
"@babel/plugin-transform-runtime": "^7.4.4",
|
||||
"@babel/preset-env": "^7.4.5",
|
||||
"@babel/register": "^7.4.4",
|
||||
|
@ -45,6 +45,9 @@ const primedBabel = babel({
|
||||
loose: true,
|
||||
modules: false
|
||||
}]
|
||||
],
|
||||
plugins: [
|
||||
'@babel/plugin-transform-object-assign'
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
*/
|
||||
import Component from './component';
|
||||
import ModalDialog from './modal-dialog';
|
||||
import mergeOptions from './utils/merge-options';
|
||||
|
||||
/**
|
||||
* A display that indicates an error has occurred. This means that the video
|
||||
@ -57,7 +56,7 @@ class ErrorDisplay extends ModalDialog {
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ErrorDisplay.prototype.options_ = mergeOptions(ModalDialog.prototype.options_, {
|
||||
ErrorDisplay.prototype.options_ = Object.assign({}, ModalDialog.prototype.options_, {
|
||||
pauseOnOpen: false,
|
||||
fillAlways: true,
|
||||
temporary: false,
|
||||
|
@ -13,6 +13,7 @@ import mergeOptions from '../utils/merge-options.js';
|
||||
import {toTitleCase} from '../utils/string-cases.js';
|
||||
import {NORMAL as TRACK_TYPES} from '../tracks/track-types';
|
||||
import setupSourceset from './setup-sourceset';
|
||||
import defineLazyProperty from '../utils/define-lazy-property.js';
|
||||
|
||||
/**
|
||||
* HTML5 Media Controller - Wrapper for HTML5 Media API
|
||||
@ -887,23 +888,27 @@ class Html5 extends Tech {
|
||||
|
||||
/* HTML5 Support Testing ---------------------------------------------------- */
|
||||
|
||||
if (Dom.isReal()) {
|
||||
|
||||
/**
|
||||
* Element for testing browser HTML5 media capabilities
|
||||
*
|
||||
* @type {Element}
|
||||
* @constant
|
||||
* @private
|
||||
*/
|
||||
Html5.TEST_VID = document.createElement('video');
|
||||
/**
|
||||
* Element for testing browser HTML5 media capabilities
|
||||
*
|
||||
* @type {Element}
|
||||
* @constant
|
||||
* @private
|
||||
*/
|
||||
defineLazyProperty(Html5, 'TEST_VID', function() {
|
||||
if (!Dom.isReal()) {
|
||||
return;
|
||||
}
|
||||
const video = document.createElement('video');
|
||||
const track = document.createElement('track');
|
||||
|
||||
track.kind = 'captions';
|
||||
track.srclang = 'en';
|
||||
track.label = 'English';
|
||||
Html5.TEST_VID.appendChild(track);
|
||||
}
|
||||
video.appendChild(track);
|
||||
|
||||
return video;
|
||||
});
|
||||
|
||||
/**
|
||||
* Check if HTML5 media is supported by this browser/device.
|
||||
@ -1115,15 +1120,12 @@ Html5.Events = [
|
||||
* @type {boolean}
|
||||
* @default {@link Html5.canControlVolume}
|
||||
*/
|
||||
Html5.prototype.featuresVolumeControl = Html5.canControlVolume();
|
||||
|
||||
/**
|
||||
* Boolean indicating whether the `Tech` supports muting volume.
|
||||
*
|
||||
* @type {bolean}
|
||||
* @default {@link Html5.canMuteVolume}
|
||||
*/
|
||||
Html5.prototype.featuresMuteControl = Html5.canMuteVolume();
|
||||
|
||||
/**
|
||||
* Boolean indicating whether the `Tech` supports changing the speed at which the media
|
||||
@ -1134,7 +1136,6 @@ Html5.prototype.featuresMuteControl = Html5.canMuteVolume();
|
||||
* @type {boolean}
|
||||
* @default {@link Html5.canControlPlaybackRate}
|
||||
*/
|
||||
Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate();
|
||||
|
||||
/**
|
||||
* Boolean indicating whether the `Tech` supports the `sourceset` event.
|
||||
@ -1142,7 +1143,35 @@ Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate();
|
||||
* @type {boolean}
|
||||
* @default
|
||||
*/
|
||||
Html5.prototype.featuresSourceset = Html5.canOverrideAttributes();
|
||||
/**
|
||||
* Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @default {@link Html5.supportsNativeTextTracks}
|
||||
*/
|
||||
/**
|
||||
* Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @default {@link Html5.supportsNativeVideoTracks}
|
||||
*/
|
||||
/**
|
||||
* Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @default {@link Html5.supportsNativeAudioTracks}
|
||||
*/
|
||||
[
|
||||
['featuresVolumeControl', 'canControlVolume'],
|
||||
['featuresMuteControl', 'canMuteVolume'],
|
||||
['featuresPlaybackRate', 'canControlPlaybackRate'],
|
||||
['featuresSourceset', 'canOverrideAttributes'],
|
||||
['featuresNativeTextTracks', 'supportsNativeTextTracks'],
|
||||
['featuresNativeVideoTracks', 'supportsNativeVideoTracks'],
|
||||
['featuresNativeAudioTracks', 'supportsNativeAudioTracks']
|
||||
].forEach(function([key, fn]) {
|
||||
defineLazyProperty(Html5.prototype, key, () => Html5[fn](), false);
|
||||
});
|
||||
|
||||
/**
|
||||
* Boolean indicating whether the `HTML5` tech currently supports the media element
|
||||
@ -1182,40 +1211,18 @@ Html5.prototype.featuresProgressEvents = true;
|
||||
*/
|
||||
Html5.prototype.featuresTimeupdateEvents = true;
|
||||
|
||||
/**
|
||||
* Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @default {@link Html5.supportsNativeTextTracks}
|
||||
*/
|
||||
Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks();
|
||||
|
||||
/**
|
||||
* Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @default {@link Html5.supportsNativeVideoTracks}
|
||||
*/
|
||||
Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks();
|
||||
|
||||
/**
|
||||
* Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @default {@link Html5.supportsNativeAudioTracks}
|
||||
*/
|
||||
Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks();
|
||||
|
||||
// HTML5 Feature detection and Device Fixes --------------------------------- //
|
||||
const canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType;
|
||||
const mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
|
||||
let canPlayType;
|
||||
|
||||
Html5.patchCanPlayType = function() {
|
||||
|
||||
// Android 4.0 and above can play HLS to some extent but it reports being unable to do so
|
||||
// Firefox and Chrome report correctly
|
||||
if (browser.ANDROID_VERSION >= 4.0 && !browser.IS_FIREFOX && !browser.IS_CHROME) {
|
||||
canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType;
|
||||
Html5.TEST_VID.constructor.prototype.canPlayType = function(type) {
|
||||
const mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
|
||||
|
||||
if (type && mpegurlRE.test(type)) {
|
||||
return 'maybe';
|
||||
}
|
||||
@ -1227,7 +1234,9 @@ Html5.patchCanPlayType = function() {
|
||||
Html5.unpatchCanPlayType = function() {
|
||||
const r = Html5.TEST_VID.constructor.prototype.canPlayType;
|
||||
|
||||
Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
|
||||
if (canPlayType) {
|
||||
Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
||||
|
@ -8,8 +8,6 @@ import AudioTrack from './audio-track';
|
||||
import VideoTrack from './video-track';
|
||||
import HTMLTrackElement from './html-track-element';
|
||||
|
||||
import mergeOptions from '../utils/merge-options';
|
||||
|
||||
/*
|
||||
* This file contains all track properties that are used in
|
||||
* player.js, tech.js, html5.js and possibly other techs in the future.
|
||||
@ -55,7 +53,7 @@ const REMOTE = {
|
||||
}
|
||||
};
|
||||
|
||||
const ALL = mergeOptions(NORMAL, REMOTE);
|
||||
const ALL = Object.assign({}, NORMAL, REMOTE);
|
||||
|
||||
REMOTE.names = Object.keys(REMOTE);
|
||||
NORMAL.names = Object.keys(NORMAL);
|
||||
|
33
src/js/utils/define-lazy-property.js
Normal file
33
src/js/utils/define-lazy-property.js
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Object.defineProperty but "lazy", which means that the value is only set after
|
||||
* it retrieved the first time, rather than being set right away.
|
||||
*
|
||||
* @param {Object} obj the object to set the property on
|
||||
* @param {string} key the key for the property to set
|
||||
* @param {Function} getValue the function used to get the value when it is needed.
|
||||
* @param {boolean} setter wether a setter shoould be allowed or not
|
||||
*/
|
||||
const defineLazyProperty = function(obj, key, getValue, setter = true) {
|
||||
const set = (value) =>
|
||||
Object.defineProperty(obj, key, {value, enumerable: true, writable: true});
|
||||
|
||||
const options = {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get() {
|
||||
const value = getValue();
|
||||
|
||||
set(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
if (setter) {
|
||||
options.set = set;
|
||||
}
|
||||
|
||||
return Object.defineProperty(obj, key, options);
|
||||
};
|
||||
|
||||
export default defineLazyProperty;
|
@ -20,7 +20,12 @@ import computedStyle from './computed-style';
|
||||
*
|
||||
*/
|
||||
function isNonBlankString(str) {
|
||||
return typeof str === 'string' && (/\S/).test(str);
|
||||
// we use str.trim as it will trim any whitespace characters
|
||||
// from the front or back of non-whitespace characters. aka
|
||||
// Any string that contains non-whitespace characters will
|
||||
// still contain them after `trim` but whitespace only strings
|
||||
// will have a length of 0, failing this check.
|
||||
return typeof str === 'string' && Boolean(str.trim());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -35,7 +40,8 @@ function isNonBlankString(str) {
|
||||
* Throws an error if there is whitespace in the string.
|
||||
*/
|
||||
function throwIfWhitespace(str) {
|
||||
if ((/\s/).test(str)) {
|
||||
// str.indexOf instead of regex because str.indexOf is faster performance wise.
|
||||
if (str.indexOf(' ') >= 0) {
|
||||
throw new Error('class has illegal whitespace characters');
|
||||
}
|
||||
}
|
||||
@ -159,7 +165,7 @@ export function createEl(tagName = 'div', properties = {}, attributes = {}, cont
|
||||
// method for it.
|
||||
} else if (propName === 'textContent') {
|
||||
textContent(el, val);
|
||||
} else {
|
||||
} else if (el[propName] !== val) {
|
||||
el[propName] = val;
|
||||
}
|
||||
});
|
||||
|
@ -87,6 +87,9 @@ function _handleMultipleEvents(fn, elem, types, callback) {
|
||||
* Fixed event object.
|
||||
*/
|
||||
export function fixEvent(event) {
|
||||
if (event.fixed_) {
|
||||
return event;
|
||||
}
|
||||
|
||||
function returnTrue() {
|
||||
return true;
|
||||
@ -201,6 +204,7 @@ export function fixEvent(event) {
|
||||
}
|
||||
}
|
||||
|
||||
event.fixed_ = true;
|
||||
// Returns fixed-up instance
|
||||
return event;
|
||||
}
|
||||
@ -208,22 +212,27 @@ export function fixEvent(event) {
|
||||
/**
|
||||
* Whether passive event listeners are supported
|
||||
*/
|
||||
let _supportsPassive = false;
|
||||
let _supportsPassive;
|
||||
|
||||
(function() {
|
||||
try {
|
||||
const opts = Object.defineProperty({}, 'passive', {
|
||||
get() {
|
||||
_supportsPassive = true;
|
||||
}
|
||||
});
|
||||
const supportsPassive = function() {
|
||||
if (typeof _supportsPassive !== 'boolean') {
|
||||
_supportsPassive = false;
|
||||
try {
|
||||
const opts = Object.defineProperty({}, 'passive', {
|
||||
get() {
|
||||
_supportsPassive = true;
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('test', null, opts);
|
||||
window.removeEventListener('test', null, opts);
|
||||
} catch (e) {
|
||||
// disregard
|
||||
window.addEventListener('test', null, opts);
|
||||
window.removeEventListener('test', null, opts);
|
||||
} catch (e) {
|
||||
// disregard
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
return _supportsPassive;
|
||||
};
|
||||
|
||||
/**
|
||||
* Touch events Chrome expects to be passive
|
||||
@ -310,7 +319,7 @@ export function on(elem, type, fn) {
|
||||
if (elem.addEventListener) {
|
||||
let options = false;
|
||||
|
||||
if (_supportsPassive &&
|
||||
if (supportsPassive() &&
|
||||
passiveEvents.indexOf(type) > -1) {
|
||||
options = {passive: true};
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import xhr from 'xhr';
|
||||
// Include the built-in techs
|
||||
import Tech from './tech/tech.js';
|
||||
import { use as middlewareUse, TERMINATOR } from './tech/middleware.js';
|
||||
import defineLazyProperty from './utils/define-lazy-property.js';
|
||||
|
||||
/**
|
||||
* Normalize an `id` value by trimming off a leading `#`
|
||||
@ -566,5 +567,7 @@ videojs.dom = Dom;
|
||||
*/
|
||||
videojs.url = Url;
|
||||
|
||||
videojs.defineLazyProperty = defineLazyProperty;
|
||||
|
||||
export default videojs;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user