1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @flow strict-local
    
  8.  */
    
  9. 
    
  10. import {__PERFORMANCE_PROFILE__} from './constants';
    
  11. 
    
  12. const supportsUserTiming =
    
  13.   typeof performance !== 'undefined' &&
    
  14.   // $FlowFixMe[method-unbinding]
    
  15.   typeof performance.mark === 'function' &&
    
  16.   // $FlowFixMe[method-unbinding]
    
  17.   typeof performance.clearMarks === 'function';
    
  18. 
    
  19. const supportsPerformanceNow =
    
  20.   // $FlowFixMe[method-unbinding]
    
  21.   typeof performance !== 'undefined' && typeof performance.now === 'function';
    
  22. 
    
  23. function mark(markName: string): void {
    
  24.   if (supportsUserTiming) {
    
  25.     performance.mark(markName + '-start');
    
  26.   }
    
  27. }
    
  28. 
    
  29. function measure(markName: string): void {
    
  30.   if (supportsUserTiming) {
    
  31.     performance.mark(markName + '-end');
    
  32.     performance.measure(markName, markName + '-start', markName + '-end');
    
  33.     performance.clearMarks(markName + '-start');
    
  34.     performance.clearMarks(markName + '-end');
    
  35.   }
    
  36. }
    
  37. 
    
  38. function now(): number {
    
  39.   if (supportsPerformanceNow) {
    
  40.     return performance.now();
    
  41.   }
    
  42.   return Date.now();
    
  43. }
    
  44. 
    
  45. export async function withAsyncPerfMeasurements<TReturn>(
    
  46.   markName: string,
    
  47.   callback: () => Promise<TReturn>,
    
  48.   onComplete?: number => void,
    
  49. ): Promise<TReturn> {
    
  50.   const start = now();
    
  51.   if (__PERFORMANCE_PROFILE__) {
    
  52.     mark(markName);
    
  53.   }
    
  54.   const result = await callback();
    
  55. 
    
  56.   if (__PERFORMANCE_PROFILE__) {
    
  57.     measure(markName);
    
  58.   }
    
  59. 
    
  60.   if (onComplete != null) {
    
  61.     const duration = now() - start;
    
  62.     onComplete(duration);
    
  63.   }
    
  64. 
    
  65.   return result;
    
  66. }
    
  67. 
    
  68. export function withSyncPerfMeasurements<TReturn>(
    
  69.   markName: string,
    
  70.   callback: () => TReturn,
    
  71.   onComplete?: number => void,
    
  72. ): TReturn {
    
  73.   const start = now();
    
  74.   if (__PERFORMANCE_PROFILE__) {
    
  75.     mark(markName);
    
  76.   }
    
  77.   const result = callback();
    
  78. 
    
  79.   if (__PERFORMANCE_PROFILE__) {
    
  80.     measure(markName);
    
  81.   }
    
  82. 
    
  83.   if (onComplete != null) {
    
  84.     const duration = now() - start;
    
  85.     onComplete(duration);
    
  86.   }
    
  87. 
    
  88.   return result;
    
  89. }
    
  90. 
    
  91. export function withCallbackPerfMeasurements<TReturn>(
    
  92.   markName: string,
    
  93.   callback: (done: () => void) => TReturn,
    
  94.   onComplete?: number => void,
    
  95. ): TReturn {
    
  96.   const start = now();
    
  97.   if (__PERFORMANCE_PROFILE__) {
    
  98.     mark(markName);
    
  99.   }
    
  100. 
    
  101.   const done = () => {
    
  102.     if (__PERFORMANCE_PROFILE__) {
    
  103.       measure(markName);
    
  104.     }
    
  105. 
    
  106.     if (onComplete != null) {
    
  107.       const duration = now() - start;
    
  108.       onComplete(duration);
    
  109.     }
    
  110.   };
    
  111.   return callback(done);
    
  112. }