All files / lib/core/utils profiler.js

65.45% Statements 72/110
86.95% Branches 20/23
100% Functions 2/2
65.45% Lines 72/110

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 505x 2715x 2715x 2715x 2715x 2715x 2715x 2715x 2705x 2705x 10x 10x 10x 10x 10x 10x 10x 10x 10x 15x                                                     10x 10x 10x 15x   15x 10x 10x 10x 10x 15x                       2715x 505x 505x 505x 505x 505x 505x 505x 505x 1281x 1281x 2083x 1255x 1255x 1255x 1253x 1255x 1255x 1255x 1255x 1255x 1255x 828x 828x 26x 33x 1281x 1281x 1281x 1281x 1281x 1281x  
let markCounter = 0;
 
/**
 * Wraps an execution block with performance marks and measures.
 * @param {boolean} enableProfiling - Whether profiling is enabled.
 * @param {string} componentName - Name of the component.
 * @param {string} phase - The phase being profiled (e.g. 'mount', 'patch', 'render', 'onMount').
 * @param {Function} fn - The function/callback to execute.
 * @returns {any} The result of the callback.
 */
export function profile(enableProfiling, componentName, phase, fn) {
  const isProfiling =
    enableProfiling &&
    typeof performance !== 'undefined' &&
    typeof performance.mark === 'function' &&
    typeof performance.measure === 'function';
 
  if (!isProfiling) {
    return fn();
  }
 
  const id = ++markCounter;
  const startMark = `ax-start-${componentName}-${phase}-${id}`;
  const endMark = `ax-end-${componentName}-${phase}-${id}`;
  const measureName = `[Avenx] ${componentName} - ${phase}`;
 
  performance.mark(startMark);
  try {
    const result = fn();
    if (result instanceof Promise) {
      return result
        .then((val) => {
          performance.mark(endMark);
          try {
            performance.measure(measureName, startMark, endMark);
          } catch {
            // Ignore
          } finally {
            performance.clearMarks(startMark);
            performance.clearMarks(endMark);
          }
          return val;
        })
        .catch((err) => {
          performance.mark(endMark);
          try {
            performance.measure(measureName, startMark, endMark);
          } catch {
            // Ignore
          } finally {
            performance.clearMarks(startMark);
            performance.clearMarks(endMark);
          }
          throw err;
        });
    }
    performance.mark(endMark);
    try {
      performance.measure(measureName, startMark, endMark);
    } catch {
      // Ignore
    } finally {
      performance.clearMarks(startMark);
      performance.clearMarks(endMark);
    }
    return result;
  } catch (err) {
    performance.mark(endMark);
    try {
      performance.measure(measureName, startMark, endMark);
    } catch {
      // Ignore
    } finally {
      performance.clearMarks(startMark);
      performance.clearMarks(endMark);
    }
    throw err;
  }
}
 
/**
 * Searches the DOM tree upwards from an element to find the nearest Avenx component.
 * Returns profiling status and the component name.
 * @param {Element|null} element - The DOM element.
 * @returns {{enableProfiling: boolean, componentName: string}}
 */
export function getComponentProfilingInfo(element) {
  let cur = element;
  while (cur) {
    if (cur.__avenx_comp_instance) {
      const comp = cur.__avenx_comp_instance;
      const enableProfiling = !!(
        comp.$app?.enableProfiling ||
        (typeof window !== 'undefined' && window.__avenx_enable_profiling)
      );
      return {
        enableProfiling,
        componentName: comp.constructor.name,
      };
    }
    cur = cur.parentNode;
  }
  const globalProfiling = !!(
    typeof window !== 'undefined' && window.__avenx_enable_profiling
  );
  return {
    enableProfiling: globalProfiling,
    componentName: 'UnknownComponent',
  };
}