Speedup embed first paint

pull/2356/head
Chocobozzz 2019-12-17 11:20:24 +01:00
parent f88ee4a952
commit 3f9c4955af
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
8 changed files with 117 additions and 66 deletions

View File

@ -137,6 +137,10 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
this.router.navigate([ '/login' ])
}
cancelCommentReply () {
this.cancel.emit(null)
}
private addCommentReply (commentCreate: VideoCommentCreate) {
return this.videoCommentService
.addCommentReply(this.video.id, this.parentComment.id, commentCreate)
@ -146,8 +150,4 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
return this.videoCommentService
.addCommentThread(this.video.id, commentCreate)
}
private cancelCommentReply () {
this.cancel.emit(null)
}
}

View File

@ -15,11 +15,12 @@ import './videojs-components/peertube-load-progress-bar'
import './videojs-components/theater-button'
import { P2PMediaLoaderPluginOptions, UserWatching, VideoJSCaption, VideoJSPluginOptions, videojsUntyped } from './peertube-videojs-typings'
import { buildVideoEmbed, buildVideoLink, copyToClipboard, getRtcConfig } from './utils'
import { getCompleteLocale, getShortLocale, is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n'
import { isDefaultLocale } from '../../../../shared/models/i18n/i18n'
import { segmentValidatorFactory } from './p2p-media-loader/segment-validator'
import { segmentUrlBuilderFactory } from './p2p-media-loader/segment-url-builder'
import { RedundancyUrlManager } from './p2p-media-loader/redundancy-url-manager'
import { getStoredP2PEnabled } from './peertube-player-local-storage'
import { TranslationsManager } from './translations-manager'
// Change 'Playback Rate' to 'Speed' (smaller for our settings menu)
videojsUntyped.getComponent('PlaybackRateMenuButton').prototype.controlText_ = 'Speed'
@ -86,24 +87,9 @@ export type PeertubePlayerManagerOptions = {
}
export class PeertubePlayerManager {
private static videojsLocaleCache: { [ path: string ]: any } = {}
private static playerElementClassName: string
private static onPlayerChange: (player: any) => void
static getServerTranslations (serverUrl: string, locale: string) {
const path = PeertubePlayerManager.getLocalePath(serverUrl, locale)
// It is the default locale, nothing to translate
if (!path) return Promise.resolve(undefined)
return fetch(path + '/server.json')
.then(res => res.json())
.catch(err => {
console.error('Cannot get server translations', err)
return undefined
})
}
static async initialize (mode: PlayerMode, options: PeertubePlayerManagerOptions, onPlayerChange: (player: any) => void) {
let p2pMediaLoader: any
@ -120,7 +106,7 @@ export class PeertubePlayerManager {
const videojsOptions = this.getVideojsOptions(mode, options, p2pMediaLoader)
await this.loadLocaleInVideoJS(options.common.serverUrl, options.common.language)
await TranslationsManager.loadLocaleInVideoJS(options.common.serverUrl, options.common.language, videojs)
const self = this
return new Promise(res => {
@ -181,32 +167,6 @@ export class PeertubePlayerManager {
})
}
private static loadLocaleInVideoJS (serverUrl: string, locale: string) {
const path = PeertubePlayerManager.getLocalePath(serverUrl, locale)
// It is the default locale, nothing to translate
if (!path) return Promise.resolve(undefined)
let p: Promise<any>
if (PeertubePlayerManager.videojsLocaleCache[path]) {
p = Promise.resolve(PeertubePlayerManager.videojsLocaleCache[path])
} else {
p = fetch(path + '/player.json')
.then(res => res.json())
.then(json => {
PeertubePlayerManager.videojsLocaleCache[path] = json
return json
})
.catch(err => {
console.error('Cannot get player translations', err)
return undefined
})
}
const completeLocale = getCompleteLocale(locale)
return p.then(json => videojs.addLanguage(getShortLocale(completeLocale), json))
}
private static getVideojsOptions (mode: PlayerMode, options: PeertubePlayerManagerOptions, p2pMediaLoaderModule?: any) {
const commonOptions = options.common
@ -519,14 +479,6 @@ export class PeertubePlayerManager {
}
})
}
private static getLocalePath (serverUrl: string, locale: string) {
const completeLocale = getCompleteLocale(locale)
if (!is18nLocale(completeLocale) || isDefaultLocale(completeLocale)) return undefined
return serverUrl + '/client/locales/' + completeLocale
}
}
// ############################################################################

View File

@ -0,0 +1,52 @@
import { getCompleteLocale, getShortLocale, is18nLocale, isDefaultLocale } from '../../../../shared/models'
export class TranslationsManager {
private static videojsLocaleCache: { [ path: string ]: any } = {}
static getServerTranslations (serverUrl: string, locale: string) {
const path = TranslationsManager.getLocalePath(serverUrl, locale)
// It is the default locale, nothing to translate
if (!path) return Promise.resolve(undefined)
return fetch(path + '/server.json')
.then(res => res.json())
.catch(err => {
console.error('Cannot get server translations', err)
return undefined
})
}
static loadLocaleInVideoJS (serverUrl: string, locale: string, videojs: any) {
const path = TranslationsManager.getLocalePath(serverUrl, locale)
// It is the default locale, nothing to translate
if (!path) return Promise.resolve(undefined)
let p: Promise<any>
if (TranslationsManager.videojsLocaleCache[ path ]) {
p = Promise.resolve(TranslationsManager.videojsLocaleCache[ path ])
} else {
p = fetch(path + '/player.json')
.then(res => res.json())
.then(json => {
TranslationsManager.videojsLocaleCache[ path ] = json
return json
})
.catch(err => {
console.error('Cannot get player translations', err)
return undefined
})
}
const completeLocale = getCompleteLocale(locale)
return p.then(json => videojs.addLanguage(getShortLocale(completeLocale), json))
}
private static getLocalePath (serverUrl: string, locale: string) {
const completeLocale = getCompleteLocale(locale)
if (!is18nLocale(completeLocale) || isDefaultLocale(completeLocale)) return undefined
return serverUrl + '/client/locales/' + completeLocale
}
}

View File

@ -43,7 +43,6 @@ export class PeerTubeEmbedApi {
channel.bind('setPlaybackRate', (txn, playbackRate) => this.embed.player.playbackRate(playbackRate))
channel.bind('getPlaybackRate', (txn, params) => this.embed.player.playbackRate())
channel.bind('getPlaybackRates', (txn, params) => this.embed.playerOptions.playbackRates)
this.channel = channel
}

View File

@ -22,5 +22,7 @@
<video playsinline="true" id="video-container" class="video-js vjs-peertube-skin">
</video>
<div id="placeholder-preview" />
</body>
</html>

View File

@ -79,6 +79,16 @@ html, body {
}
}
#placeholder-preview {
position: absolute;
top: 0;
left: 0;
background-size: 100% auto;
width: 100%;
height: 100%;
background-position: 50% 50%;
}
@media screen and (max-width: 300px) {
#error-block {
font-size: 36px;

View File

@ -1,16 +1,24 @@
import './embed.scss'
import { peertubeTranslate, ResultList, ServerConfig, VideoDetails } from '../../../../shared'
import {
getCompleteLocale,
is18nLocale,
isDefaultLocale,
peertubeTranslate,
ResultList,
ServerConfig,
VideoDetails
} from '../../../../shared'
import { VideoJSCaption } from '../../assets/player/peertube-videojs-typings'
import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
import {
P2PMediaLoaderOptions,
PeertubePlayerManager,
PeertubePlayerManagerOptions,
PlayerMode
} from '../../assets/player/peertube-player-manager'
import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type'
import { PeerTubeEmbedApi } from './embed-api'
import { TranslationsManager } from '../../assets/player/translations-manager'
export class PeerTubeEmbed {
videoElement: HTMLVideoElement
@ -154,20 +162,30 @@ export class PeerTubeEmbed {
const urlParts = window.location.pathname.split('/')
const videoId = urlParts[ urlParts.length - 1 ]
const [ serverTranslations, videoResponse, captionsResponse, configResponse ] = await Promise.all([
PeertubePlayerManager.getServerTranslations(window.location.origin, navigator.language),
this.loadVideoInfo(videoId),
this.loadVideoCaptions(videoId),
this.loadConfig()
])
const videoPromise = this.loadVideoInfo(videoId)
const captionsPromise = this.loadVideoCaptions(videoId)
const configPromise = this.loadConfig()
const translationsPromise = TranslationsManager.getServerTranslations(window.location.origin, navigator.language)
const videoResponse = await videoPromise
if (!videoResponse.ok) {
const serverTranslations = await translationsPromise
if (videoResponse.status === 404) return this.videoNotFound(serverTranslations)
return this.videoFetchError(serverTranslations)
}
const videoInfo: VideoDetails = await videoResponse.json()
this.loadPlaceholder(videoInfo)
const PeertubePlayerManagerModulePromise = import('../../assets/player/peertube-player-manager')
const promises = [ translationsPromise, captionsPromise, configPromise, PeertubePlayerManagerModulePromise ]
const [ serverTranslations, captionsResponse, configResponse, PeertubePlayerManagerModule ] = await Promise.all(promises)
const PeertubePlayerManager = PeertubePlayerManagerModule.PeertubePlayerManager
const videoCaptions = await this.buildCaptions(serverTranslations, captionsResponse)
this.loadParams(videoInfo)
@ -220,7 +238,7 @@ export class PeerTubeEmbed {
})
}
this.player = await PeertubePlayerManager.initialize(this.mode, options, player => this.player = player)
this.player = await PeertubePlayerManager.initialize(this.mode, options, (player: any) => this.player = player)
this.player.on('customError', (event: any, data: any) => this.handleError(data.err, serverTranslations))
window[ 'videojsPlayer' ] = this.player
@ -230,6 +248,8 @@ export class PeerTubeEmbed {
await this.buildDock(videoInfo, configResponse)
this.initializeApi()
this.removePlaceholder()
}
private handleError (err: Error, translations?: { [ id: string ]: string }) {
@ -282,6 +302,22 @@ export class PeerTubeEmbed {
return []
}
private loadPlaceholder (video: VideoDetails) {
const placeholder = this.getPlaceholderElement()
const url = window.location.origin + video.previewPath
placeholder.style.backgroundImage = `url("${url}")`
}
private removePlaceholder () {
const placeholder = this.getPlaceholderElement()
placeholder.parentElement.removeChild(placeholder)
}
private getPlaceholderElement () {
return document.getElementById('placeholder-preview')
}
}
PeerTubeEmbed.main()

View File

@ -5,5 +5,5 @@ set -eu
gawk -i inplace 'BEGIN { found=0 } { if (found || $0 ~ /^{/) { found=1; print }}' ./client/dist/embed-stats.json
npm run concurrently -- -k \
"cd client && npm run webpack-bundle-analyzer -- -p 8888 ./dist/en_US/stats-es2015.json" \
"cd client && npm run webpack-bundle-analyzer -- -p 8888 ./dist/en-US/stats-es2015.json" \
"cd client && npm run webpack-bundle-analyzer -- -p 8889 ./dist/embed-stats.json"