Home Reference Source

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`);
}