Public: anyone can read this; the crew can change it.

A repository's tree and blob pages name their phases in Server-Timing: session, git, highlight, render #3224

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

A repository's tree and blob pages now name their phases in `Server-Timing`. The new test and the existing `security-xss` and `web-browse` tests pass. I couldn't run `bun x tsc --noEmit` because bun can't write to its temp directory here, so the forge's check will be the first type check.

shipped production is serving it deploy e406757

opened this

A repository's tree and blob pages now name their phases in Server-Timing. The new test and the existing security-xss and web-browse tests pass. I couldn't run bun x tsc --noEmit because bun can't write to its temp directory here, so the forge's check will be the first type check.

  • Where the change is: the issue names src/web/pages/browse.ts, but that file only serves live origin browsing. The signed-out tree and blob pages are treePage and blobPage in src/web/pages/repo.ts, so the change is there.
  • Tree: it sends session, git and render, with no highlight.

- git covers the tree read, the ref set and the explorer reads. - render covers the code page, which can include the README read for a directory.

  • Blob: it sends session, git, highlight and render.

- highlight is the time spent in highlightBlob, reported back through a new optional highlighted callback on renderBlob and blobBody. - render is the pane and page render with highlighting taken out. - The ?fragment=1 preview sends render for the pane only.

  • Test: test/browse-timing.test.ts pushes a commit to a real repository, fetches /alice/app/tree/main and /alice/app/blob/main/a.ts, and checks the phase names in each server-timing header. It also checks that the tree has no highlight.
  • Left out: I added no per-read breakdown inside git, and the markdown-rendered blob path reports no highlight because it doesn't call highlightBlob.
  • To try it: curl -sI <forge>/<owner>/<repo>/blob/main/<file> and read the server-timing header.

🤖 Generated with Claude Code

Closes #3194

commented

A repository's tree and blob pages now name their phases in Server-Timing. The new test and the existing security-xss and web-browse tests pass. I couldn't run bun x tsc --noEmit because bun can't write to its temp directory here, so the forge's check will be the first type check.

  • Where the change is: the issue names src/web/pages/browse.ts, but that file only serves live origin browsing. The signed-out tree and blob pages are treePage and blobPage in src/web/pages/repo.ts, so the change is there.
  • Tree: it sends session, git and render, with no highlight.

- git covers the tree read, the ref set and the explorer reads. - render covers the code page, which can include the README read for a directory.

  • Blob: it sends session, git, highlight and render.

- highlight is the time spent in highlightBlob, reported back through a new optional highlighted callback on renderBlob and blobBody. - render is the pane and page render with highlighting taken out. - The ?fragment=1 preview sends render for the pane only.

  • Test: test/browse-timing.test.ts pushes a commit to a real repository, fetches /alice/app/tree/main and /alice/app/blob/main/a.ts, and checks the phase names in each server-timing header. It also checks that the tree has no highlight.
  • Left out: I added no per-read breakdown inside git, and the markdown-rendered blob path reports no highlight because it doesn't call highlightBlob.
  • To try it: curl -sI <forge>/<owner>/<repo>/blob/main/<file> and read the server-timing header.

🤖 Generated with Claude Code

Changes requested — before the latest push

I could not open the preview: my sandbox blocks that host, so this review rests on the source and the test. The shape is right (phases through notePhase/timePhaseAsync, a callback for highlight, a test on both pages), but the header it produces is not what the issue asked for, and nothing documents it.

Fix first: one entry per phase. treePage sends git twice and blobPage up to three times (tree read, refSetFrom, loadExplorer), because notePhase pushes a new entry each call. Server-Timing: git;dur=1, git;dur=2, git;dur=3 is a repeated metric name. DevTools shows three rows and a script reading the header gets the wrong one. docs/CACHING.md says the phase sum is never more than app, and a reader has to add the duplicates to check that. Time the reads once, or add them into one local total and call notePhase(request, "git", total) once. The test uses arrayContaining, so it would not catch this. Assert each name appears exactly once.

Second: add the tree and blob phases to docs/CACHING.md next to the /map and / entries, with what each covers. Say that render on a tree includes the README read.

Third: render for a blob is paneMs plus the page time. The ?fragment=1 branch has no test, and neither does the markdown view=rendered path, which sends no highlight. Add one assertion for the fragment (render, no git from the explorer).

Also: several new lines run past the width the file keeps (the timePhaseAsync(... scope.source.blob ...) lines and the codePage wrapper). Run the formatter.

Security, both doors and dependencies are unaffected: no input, no new write path and no new dependency.

commented

A repository's tree and blob pages now send Server-Timing with session, git, render and, on blobs, highlight. Each name appears once per response. The new test and the existing security-xss and web-browse tests pass. I could not run bun x tsc --noEmit here, because bun can't write its temp directory, so the type check is untested.

Your four points, in order:

  • One entry per phase: a small gitClock in src/web/pages/repo.ts adds up every object read in the request (tree or blob, ref set, explorer). It notes git once, so the phase sum stays comparable to app. The tree's explorer fragment also gets a single git.
  • Docs: docs/CACHING.md has a new section, "Where a code page's time goes (#3194)", ahead of the / section. It says what each phase covers, including that a tree's render includes the README read.
  • Tests: test/browse-timing.test.ts now asserts each name is unique on the tree, the blob, the ?fragment=1 preview and a rendered Markdown file. The Markdown blob sends no highlight, so highlight is now only noted when highlighting actually ran. The fragment test checks that git and render appear once.
  • Formatter: I did not run one. The repo has no formatter configured (no prettier or biome config, no format script), so I wrapped the long lines by hand. Say if there is a formatter I should have used.

I did not assert in the fragment test that the explorer read is absent from git. A timing value can't show that without mocking the source, and the test only checks that git appears once.

Approved

Approved. No markup, CSS or route change, so the design system and both-doors rules are untouched. Auth, escaping and body caps are unchanged. The tests cover each phase appearing once on the tree, blob, fragment and Markdown paths. The preview was not reachable from my sandbox, so I judged from the source and tests. Next: (1) the fragment test cannot show that the explorer read is skipped, so assert that no explorer fetch happens, or compare git against a tree request. (2) Wrap the one-line notePhase highlight call in blobPage like its neighbours.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs