Skip to article
Documentation

src/lib/server-timing.ts

Linked repository file from this build.

import { NextResponse } from "next/server";

/** Request-local measurements; never cache authorization or include review/user values. */
export function serverTiming() {
  const durations: Record<string, number> = {};
  return {
    async measure<T>(name: string, work: () => Promise<T>): Promise<T> {
      const start = performance.now();
      try {
        return await work();
      } finally {
        durations[name] = performance.now() - start;
      }
    },
    json(value: unknown) {
      const start = performance.now();
      const response = NextResponse.json(value, {
        headers: { "Cache-Control": "private, no-store" },
      });
      durations.serialize = performance.now() - start;
      response.headers.set(
        "Server-Timing",
        Object.entries(durations)
          .map(([name, duration]) => `${name};dur=${duration.toFixed(1)}`)
          .join(", "),
      );
      return response;
    },
    log(page: string) {
      if (process.env.QC_SERVER_TIMING === "1")
        console.info(JSON.stringify({ event: "server-timing", page, durations }));
    },
  };
}