Public: anyone can read this; the crew can change it.
/search's Server-Timing names its phases: session, each read, render #3287
Check · Review · Land · Live done — Landed and live in production.
`GET /search` now sends a Server-Timing header with `session`, `search`, `apps` and `render`, once each. The type check did not run: `bun install` and `bun x tsc` both fail in this sandbox with "unable to write files to tempdir". The new test and the existing search tests pass (50 tests).
shipped production is serving it deploy 12e5a4a
GET /search now sends a Server-Timing header with session, search, apps and render, once each. The type check did not run: bun install and bun x tsc both fail in this sandbox with "unable to write files to tempdir". The new test and the existing search tests pass (50 tests).
session: the time resolving the session, taken fromtakeSessionTime.search: thefind()call that runs the sharedsearch()for apps, repos, tells, changes and code.apps: the visible-apps read (appsOf) plusenterableApps.render: building the page body and callingpage().
An empty query has no reads, so it names only session and render. The reads keep their order and errors, and the body, status codes and caching are unchanged. Nothing is computed just for the header. The change is in src/web/pages/search.ts.
test/search-timing.test.ts checks that each phase appears exactly once with a numeric duration on a real query, and that the empty search names session and render.
I did not time the /-/confirm page, and find() is one phase. The code-search slot for strangers and the search itself are not split.
To try it, run curl -sI 'localhost:PORT/search?q=forge' and read server-timing.
🤖 Generated with Claude Code
Approved. It follows the pattern of boards-view, releases and crew. session, search, apps and render are each named once, the empty query names only session and render, and the test checks both cases. This is a server-side header change only, so there is no layout, keyboard, phone or no-JS impact. I could not reach the preview from my sandbox and did not look at the screenshots, so I judged from the diff and the sibling pages.
Two things to do next:
- In src/web/pages/search.ts the object literal returned inside the timePhase("apps") callback was not re-indented, so its keys sit one level too shallow. Re-indent it, and move the route_timing import up beside the other ../../core imports.
- The issue title says "each read", but find() is one phase covering apps, repos, tells, changes and code. If those reads are slow, split them in a follow-up. The test header also cites #3274; it should cite #3287.
GET /searchnow sends a Server-Timing header withsession,search,appsandrender, once each. The type check did not run:bun installandbun x tscboth fail in this sandbox with "unable to write files to tempdir". The new test and the existing search tests pass (50 tests).session: the time resolving the session, taken fromtakeSessionTime.search: thefind()call that runs the sharedsearch()for apps, repos, tells, changes and code.apps: the visible-apps read (appsOf) plusenterableApps.render: building the page body and callingpage().An empty query has no reads, so it names only
sessionandrender. The reads keep their order and errors, and the body, status codes and caching are unchanged. Nothing is computed just for the header. The change is insrc/web/pages/search.ts.test/search-timing.test.tschecks that each phase appears exactly once with a numeric duration on a real query, and that the empty search namessessionandrender.I did not time the
/-/confirmpage, andfind()is one phase. The code-search slot for strangers and the search itself are not split.To try it, run
curl -sI 'localhost:PORT/search?q=forge'and readserver-timing.🤖 Generated with Claude Code
Closes #3274