src/performance/performance-monitor.ts
/*
* Push the performance monitor as the last core component in hls.ts
* so that it is the last class to handle events.
*
* coreComponents.push(new PerformanceMonitor(this));
*
* TODO: Add this to the demo page or a performance test page
*/
import { Events } from '../events';
import { logger } from '../utils/logger';
import Hls from '../hls';
import type { FragBufferedData } from '../types/events';
export default class PerformanceMonitor {
private hls: Hls;
constructor (hls: Hls) {
this.hls = hls;
this.hls.on(Events.FRAG_BUFFERED, this.onFragBuffered);
}
destroy () {
this.hls.off(Events.FRAG_BUFFERED);
}
onFragBuffered (event: Events.FRAG_BUFFERED, data: FragBufferedData) {
logFragStats(data);
}
}
function logFragStats (data: FragBufferedData) {
const { frag, part } = data;
const stats = part ? part.stats : frag.stats;
const tLoad = stats.loading.end - stats.loading.start;
const tBuffer = stats.buffering.end - stats.buffering.start;
const tParse = stats.parsing.end - stats.parsing.start;
const tTotal = stats.buffering.end - stats.loading.start;
logger.log(`[performance-monitor]: Stats for fragment ${frag.sn} ${part ? (' part ' + part.index) : ''} of level ${frag.level}:
Size: ${((stats.total / 1024)).toFixed(3)} kB
Chunk Count: ${stats.chunkCount}
Request: ${stats.loading.start.toFixed(3)} ms
First Byte: ${stats.loading.first.toFixed(3)} ms
Parse Start ${stats.parsing.start.toFixed(3)} ms
Buffering Start: ${stats.buffering.start.toFixed(3)} ms
First Buffer: ${stats.buffering.first.toFixed(3)} ms
Parse End: ${stats.parsing.end.toFixed(3)} ms
Buffering End: ${stats.buffering.end.toFixed(3)} ms
Load Duration: ${tLoad.toFixed(3)} ms
Parse Duration: ${(tParse).toFixed(3)} ms
Buffer Duration: ${(tBuffer).toFixed(3)} ms
End-To-End Duration: ${(tTotal).toFixed(3)} ms`);
}