Repository: honojs/hono
File: src/middleware/timing/timing.ts (TypeScript)

Code before:

export type TimingVariables = {
  metric?: {
    headers: string[]
    timers: Map<string, Timer>
  }
}

interface Timer {
  description?: string
  start: number
}

interface TimingOptions {
  total?: boolean
  enabled?: boolean | ((c: Context) => boolean)
  totalDescription?: string
  autoEnd?: boolean
  crossOrigin?: boolean | string | ((c: Context) => boolean | string)
}

const getTime = (): number => {
  try {
    return performance.now()
  } catch (e) {
    console.warn('performance.now() is not available. Falling back to Date.now()', e)
  }
  return Date.now()
}

/**
 * Server-Timing Middleware for Hono.
 *
 * @see {@link https://hono.dev/docs/middleware/builtin/timing}
 *
 * @param {TimingOptions} [config] - The options for the timing middleware.
 * @param {boolean} [config.total=true] - Show the total response time.
 * @param {boolean | ((c: Context) => boolean)} [config.enabled=true] - Whether timings should be added to the headers or not.
 * @param {string} [config.totalDescription=Total Response Time] - Description for the total response time.
 * @param {boolean} [config.autoEnd=true] - If `startTime()` should end automatically at the end of the request.
 * @param {boolean | string | ((c: Context) => boolean | string)} [config.crossOrigin=false] - The origin this timings header should be readable.
 * @returns {MiddlewareHandler} The middleware handler function.
 *
 * @example
 * ```ts
 * const app = new Hono()
 *
 * // add the middleware to your router
 * app.use(timing());
 *
 * app.get('/', async (c) => {

Review comment (performance):
There are already several `console.warn()` in this file, but these are displayed when “middleware is not set up correctly”.

This fallback to `Date.now()` is displayed when running in an environment where `performance.now()` is not available, but I don't think users would be happy if they were shown a warning for every request.

If we display a warning when it is not available, it would be better to do it like this.

```ts
diff --git a/src/middleware/timing/timing.ts b/src/middleware/timing/timing.ts
index d387f43b..f341592f 100644
--- a/src/middleware/timing/timing.ts
+++ b/src/middleware/timing/timing.ts
@@ -27,12 +27,9 @@ interface TimingOptions {
   crossOrigin?: boolean | string | ((c: Context) => boolean | string)
 }
 
-const getTime = (): number => {
-  try {
-    return performance.now()
-  } catch {}
-  return Date.now()
-}
+const getTime: () => number =
+  performance?.now?.bind(performance) ??
+  (console.warn('performance.now is not supported, using Date.now'), Date.now.bind(Date))
 
 /**
  * Server-Timing Middleware for Hono.
```

Code after:

export type TimingVariables = {
  metric?: {
    headers: string[]
    timers: Map<string, Timer>
  }
}

interface Timer {
  description?: string
  start: number
}

interface TimingOptions {
  total?: boolean
  enabled?: boolean | ((c: Context) => boolean)
  totalDescription?: string
  autoEnd?: boolean
  crossOrigin?: boolean | string | ((c: Context) => boolean | string)
}

const getTime = (): number => {
  try {
    return performance.now()
  } catch {}
  return Date.now()
}

/**
 * Server-Timing Middleware for Hono.
 *
 * @see {@link https://hono.dev/docs/middleware/builtin/timing}
 *
 * @param {TimingOptions} [config] - The options for the timing middleware.
 * @param {boolean} [config.total=true] - Show the total response time.
 * @param {boolean | ((c: Context) => boolean)} [config.enabled=true] - Whether timings should be added to the headers or not.
 * @param {string} [config.totalDescription=Total Response Time] - Description for the total response time.
 * @param {boolean} [config.autoEnd=true] - If `startTime()` should end automatically at the end of the request.
 * @param {boolean | string | ((c: Context) => boolean | string)} [config.crossOrigin=false] - The origin this timings header should be readable.
 * @returns {MiddlewareHandler} The middleware handler function.
 *
 * @example
 * ```ts
 * const app = new Hono()
 *
 * // add the middleware to your router
 * app.use(timing());
 *
 * app.get('/', async (c) => {
 *   // add custom metrics
 *   setMetric(c, 'region', 'europe-west3')