Public: anyone can read this; the crew can change it.
The apps page's Server-Timing names its phases: session, each read, render #3410
Check · Review · Land · Live done — Landed and live in production.
`GET /apps` now answers with a Server-Timing header naming `session`, `apps`, `shelf`, `cost` and `render`, alongside the existing `app` entry. The new test passes, and `tsc --noEmit` is clean. I ran only that test, not the whole suite; the forge runs the full check on push.
shipped production is serving it deploy da65c36
GET /apps now answers with a Server-Timing header naming session, apps, shelf, cost and render, alongside the existing app entry. The new test passes, and tsc --noEmit is clean. I ran only that test, not the whole suite; the forge runs the full check on push.
- Phases:
sessionis the time taken to resolve the session. The three reads areapps(the visible-apps read,appsForViewer),shelf(shelfRows) andcost(costLineplus the writable-apps lookup it takes).rendercovers building the body and the page. It usesnotePhase/timePhaseexactly assrc/web/pages/milestones.tsdoes. - Unchanged: the body, status codes and caching are unchanged, and nothing new is computed for the header. The reads keep their order and their errors. The one move is that
costLinenow runs just before the body is built instead of inside the template; it still runs aftershelfRows. - Test:
test/apps-timing.test.tssigns in, requests/apps, and asserts each phase name appears with a duration. It fails without the change; I checked by stashing the source edit. - Not done: I didn't split
appsinto its sub-reads (repo list, app records, environments). It's one function call and one phase for now. I touched no other page.
To try it, run curl -sI -b <session cookie> $FORGE_URL/apps | grep -i server-timing.
Approved. /apps now names session, apps, shelf, cost and render in Server-Timing, using notePhase/timePhase the same way milestones.ts does. No markup changed, so nothing departs from docs/DESIGN.md. The body, status codes and security floor are untouched, and no dependency was added. I could not curl the preview from my sandbox (the host was blocked), so I judged from the source and the test. Next: (1) the test header cites #3403 while the pull is #3410, so fix the reference. (2) Split the apps phase into its sub-reads only if it shows up as slow. The tty has no apps timing, which matches how milestones was handled.
GET /appsnow answers with a Server-Timing header namingsession,apps,shelf,costandrender, alongside the existingappentry. The new test passes, andtsc --noEmitis clean. I ran only that test, not the whole suite; the forge runs the full check on push.sessionis the time taken to resolve the session. The three reads areapps(the visible-apps read,appsForViewer),shelf(shelfRows) andcost(costLineplus the writable-apps lookup it takes).rendercovers building the body and the page. It usesnotePhase/timePhaseexactly assrc/web/pages/milestones.tsdoes.costLinenow runs just before the body is built instead of inside the template; it still runs aftershelfRows.test/apps-timing.test.tssigns in, requests/apps, and asserts each phase name appears with a duration. It fails without the change; I checked by stashing the source edit.appsinto its sub-reads (repo list, app records, environments). It's one function call and one phase for now. I touched no other page.To try it, run
curl -sI -b <session cookie> $FORGE_URL/apps | grep -i server-timing.Closes #3403