Public: anyone can read this; the crew can change it.
/explore's Server-Timing names its phases: session, rank, render #3234
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/3230-explore-s-server-timing-names-its-phases → main 1 commit fork 1 thread · 1 unresolved
2 files
changed +31
−1
src/web/studio/explore.ts +8 −1
| @@ -13,6 +13,7 @@ import { | ||
| 13 | 13 | type ExploreQuery, |
| 14 | 14 | type ExploreRow, |
| 15 | 15 | } from "../../actions/explore.ts"; |
| 16 | import { notePhase, takeSessionTime } from "../../core/route_timing.ts"; | |
| 16 | 17 | import type { Ctx } from "../../http/context.ts"; |
| 17 | 18 | import { pageHead } from "../chrome.ts"; |
| 18 | 19 | import { html, when, type Html } from "../html.ts"; |
| @@ -63,8 +64,12 @@ function rowHtml(row: ExploreRow): Html { | ||
| 63 | 64 | |
| 64 | 65 | // GET /explore |
| 65 | 66 | export async function explorePage(ctx: Ctx): Promise<Response> { |
| 67 | notePhase(ctx.request, "session", takeSessionTime(ctx.request)); | |
| 66 | 68 | const query = parseExploreQuery(ctx.url.searchParams.get("q") ?? ""); |
| 69 | const ranking = performance.now(); | |
| 67 | 70 | const rows = await explore(ctx.app, ctx.auth.user, query); |
| 71 | notePhase(ctx.request, "rank", performance.now() - ranking); | |
| 72 | const rendering = performance.now(); | |
| 68 | 73 | const kinds = [ |
| 69 | 74 | { label: "All", kind: "all" as const }, |
| 70 | 75 | { label: "Apps", kind: "app" as const }, |
| @@ -124,5 +129,7 @@ export async function explorePage(ctx: Ctx): Promise<Response> { | ||
| 124 | 129 | note: "Clear the line to see everything you can.", |
| 125 | 130 | }) |
| 126 | 131 | : listCard(rows.map(rowHtml))}`; |
| 127 | return page({ ctx, title: "Explore", body }); | |
| 132 | const response = page({ ctx, title: "Explore", body }); | |
| 133 | notePhase(ctx.request, "render", performance.now() - rendering); | |
| 134 | return response; | |
| 128 | 135 | } |
test/explore-timing.test.ts added +23
| @@ -0,0 +1,23 @@ | ||
| 1 | /** `/explore`'s Server-Timing names its phases: session, rank, render (#3230). */ | |
| 2 | import { afterAll, beforeAll, expect, test } from "bun:test"; | |
| 3 | import { snappyFixture, type SnappyFixture } from "../bench/snappy.ts"; | |
| 4 | ||
| 5 | let f: SnappyFixture; | |
| 6 | ||
| 7 | beforeAll(async () => { | |
| 8 | f = await snappyFixture(); | |
| 9 | }, 120_000); | |
| 10 | afterAll(async () => { | |
| 11 | await f.close(); | |
| 12 | }); | |
| 13 | ||
| 14 | for (const path of ["/explore", "/explore?q=" + encodeURIComponent("kind:app sort:forks")]) { | |
| 15 | test(`GET ${path} names session, rank and render beside the route total`, async () => { | |
| 16 | const res = await fetch(`${f.base}${path}`); | |
| 17 | await res.arrayBuffer(); | |
| 18 | expect(res.status).toBe(200); | |
| 19 | const parts = (res.headers.get("server-timing") ?? "").split(", "); | |
| 20 | for (const name of ["app", "session", "rank", "render"]) | |
| 21 | expect(parts.find((p) => p.startsWith(`${name};`))).toMatch(/^[a-z]+;dur=\d+\.\d$/); | |
| 22 | }); | |
| 23 | } |
new above
offline
The header cites #3230, but this pull is #3234. Point it at the right number.