Tracking render performance

FYI: This solution worked until now quite good. I’m now able to track when the page rendered. Sometimes there might be another render event fired because of late evaluated binding behaviors but this is catchable with a variable to only track it once. Keep in mind that the timeout add’s 1s to the tracked time which must be removed. Here is my solution.

/**
 * Extend original function with additional functionality
 * @param {Object} proto
 * @param {string} fnName
 * @param {Function} callback
 */
export function extendFn(proto: Object, fnName: string, callback: Function): void {
  const origFn = proto[fnName];
  proto[fnName] = function extendedFn() {
    let result;
    if (typeof origFn === 'function') {
      result = origFn.apply(this, arguments);
    }
    callback.apply(this, arguments);
    return result;
  };
}

/**
 * Hook into micro task queue to track when rendering is finished
 * @param {TaskQueue} taskQueue
 * @param {EventAggregator} events
 */
function hookRendering(taskQueue: TaskQueue, events: EventAggregator): void {
  let timeoutHandle;
  extendFn(taskQueue, 'flushMicroTaskQueue', () => {
    if (timeoutHandle) {
      clearTimeout(timeoutHandle);
    }
    const actual = performance.now();
    timeoutHandle = setTimeout(() => {
      events.publish('app.rendered', performance.now() - actual);
    }, 1000);
  });
}

The actual page load time can be tracked this way:

let initialPageLoad = true;
events.subscribe('app.rendered', delta => {
  if (initialPageLoad) {
    initialPageLoad = false;
    log.debug(`Page loaded in ${performance.now() - delta}ms`);
  }
})