Super Helpful: Server-Timing HTTP Response Headers

Today I (re)learned about the Server-Timing HTTP response header. (Thanks for mentioning it, Scott!) Web servers can include this header with arbitrary server timing metrics. So, you could time a common query or the process of rendering HTML and provide that metadata to the browser via a response header.

This gets really helpful when you open your development console and check the Timing view. Not only do you get the common DNS, TCP, waiting, etc metrics, but your server's custom timings will be shown with their descriptions!

So I made a small (<80 very sparse lines of code) thing to help create Server-Timing headers:

header-timers is available on npm and minimal documentation is available on the README.

Here's how it's used on my blog index, an Enhance API handler:

import arc from '@architect/functions'
import HeaderTimers from 'header-timers'

const { articles } = await arc.tables()

async function getHandler () {
  const timers = HeaderTimers()

  timers.start('dynamo', 'get articles')
  // TODO: not scan
  const query = await articles.scan({
    Limit: 100,
    FilterExpression: 'attribute_exists(published)',
    ProjectionExpression: 'title, published, slug, description, #date',
    ExpressionAttributeNames: {
      '#date': 'date'
    }
  })
  timers.stop('dynamo')

  timers.start('sort', 'articles sort')
  const sortedArticles = query.Items.filter(({ published }) => published).sort(
    (a, b) => new Date(b.date).valueOf() - new Date(a.date).valueOf()
  )
  timers.stop('sort')

  return {
    headers: {
      [timers.headerKey]: timers.headerValue()
    },
    json: { articles: sortedArticles }
  }
}

export const get = getHandler

From what I could find, existing packages have affordances for the browser (why, though?), Express, or other HTTP frameworks. Some do allow you to create timers and header values without a framework, but I don't need the overhead. Also many hadn't been updated in a while and were also using the legacy process.hrtime. header-timers uses the newer process.hrtime.bigint.

I wanted something slim I could use in "cloud functions" like Enhance API routes.

Check it out and let me know what you think!

from DynamoDB (4.9ms) to HTML (3.6ms) in 8.5ms