Server Timing

LaunchFast includes a server timing utility that lets you measure the performance of individual operations within a request. Metrics are exposed via the Server-Timing HTTP header and appear in Chrome DevTools under the Timing tab.

How it works

The utility lives in app/utils/timing.server.ts and provides three functions: makeTimings to create a timing context, time to wrap async operations, and combineServerTimings to merge timings from parent and child routes.

Usage

There are four steps to adding server timing to a route:

  1. Create a timings object
  2. Wrap functions with time()
  3. Return the header in your response
  4. Export a headers function to forward the header
import {
  combineServerTimings,
  makeTimings,
  time,
} from '#app/utils/timing.server.ts'

export async function loader({ params }: LoaderFunctionArgs) {
  const timings = makeTimings('my loader')

  const user = await time(
    () => prisma.user.findUnique({
      where: { id: params.id },
    }),
    { timings, type: 'find user' },
  )

  return json(
    { user },
    { headers: { 'Server-Timing': timings.toString() } },
  )
}

export const headers: HeadersFunction = ({
  loaderHeaders,
  parentHeaders,
}) => ({
  'Server-Timing': combineServerTimings(
    parentHeaders,
    loaderHeaders,
  ),
})

Viewing in DevTools

Open Chrome DevTools, go to the Network tab, select a request, and click the Timing tab. Your custom metrics appear in the Server Timing section at the bottom.

Combining timings across routes

Remix merges headers from nested routes using the headers export. The combineServerTimings utility merges the Server-Timing header from parent and loader headers so all timing data flows through to the browser.