perf(runtime): cache the derived runtime key
`getRuntimeKey` keys caches, stores, and persisted state across the whole UI, so it runs on store reads, event handling, and render paths. Until the runtime endpoint is explicitly initialised, every call re-derived the key by trimming two injected globals and constructing three URL objects. In a streaming capture this made `readInjectedLocalOrigin` the single most expensive application function: 315 ms of self time, 12% of all main-thread busy time. After the change it does not appear in the profile at all, and the same capture went from two long tasks to none, with the longest task dropping from 210 ms to 47 ms. The key depends only on the active API base URL and two injected globals, and `switchRuntimeEndpoint` writes the injected API base URL at runtime, so the cache is validated against the raw untrimmed values rather than memoised outright. That comparison allocates nothing and still recomputes as soon as any input changes. Tests cover both directions, including an operation-count assertion that repeated calls construct no URLs. The streaming profiler also reports output-normalised metrics, because response length varies between runs and makes per-second totals incomparable.
This commit is contained in:
@@ -187,6 +187,9 @@ const REPORTED_METRICS = [
|
||||
{ key: "layoutsPerSecond", label: "Layouts/sec", unit: "", lowerIsBetter: true },
|
||||
{ key: "framesPerSecond", label: "Animation frames/sec", unit: "", lowerIsBetter: false },
|
||||
{ key: "streamSeconds", label: "Stream duration", unit: "s", lowerIsBetter: true },
|
||||
{ key: "renderedCharacters", label: "Rendered characters", unit: "", lowerIsBetter: false },
|
||||
{ key: "busyMsPerKilochar", label: "Busy per 1k chars", unit: "ms", lowerIsBetter: true },
|
||||
{ key: "recalcStylePerKilochar", label: "Style recalcs per 1k", unit: "", lowerIsBetter: true },
|
||||
{ key: "nodeGrowth", label: "DOM node growth", unit: "", lowerIsBetter: true },
|
||||
{ key: "listenerGrowth", label: "Listener growth", unit: "", lowerIsBetter: true },
|
||||
{ key: "heapGrowthMbPerSecond", label: "Heap growth", unit: "MB/s", lowerIsBetter: true },
|
||||
@@ -429,6 +432,8 @@ const main = async () => {
|
||||
.some((entry) => entry.metric.startsWith("ui.message_list") && entry.count > 0)
|
||||
const renderedStream = renderedAfter.messages > renderedBefore.messages && messageListRendered
|
||||
|
||||
const renderedCharacterGrowth = renderedAfter.characters - renderedBefore.characters
|
||||
|
||||
const tasks = summarizeLongTasks(traceEvents)
|
||||
const delta = (name) => Number(after[name] ?? 0) - Number(before[name] ?? 0)
|
||||
const perSecond = (name) => round(delta(name) / elapsedSeconds)
|
||||
@@ -448,7 +453,7 @@ const main = async () => {
|
||||
renderedStream,
|
||||
renderedMessagesBefore: renderedBefore.messages,
|
||||
renderedMessagesAfter: renderedAfter.messages,
|
||||
renderedCharacterGrowth: renderedAfter.characters - renderedBefore.characters,
|
||||
renderedCharacterGrowth,
|
||||
traceComplete,
|
||||
disposableSession: !options.keepSession && !options.session,
|
||||
metrics: {
|
||||
@@ -458,6 +463,16 @@ const main = async () => {
|
||||
recalcStylePerSecond: perSecond("RecalcStyleCount"),
|
||||
layoutsPerSecond: perSecond("LayoutCount"),
|
||||
framesPerSecond: round(Number(probe?.counters?.rafScheduled ?? 0) / elapsedSeconds),
|
||||
// Response length varies between runs even for an identical prompt, so
|
||||
// per-second and total figures are not comparable across captures.
|
||||
// Normalising by rendered output is what makes two runs contrastable.
|
||||
renderedCharacters: renderedCharacterGrowth,
|
||||
busyMsPerKilochar: renderedCharacterGrowth > 0
|
||||
? round((delta("TaskDuration") * 1000) / (renderedCharacterGrowth / 1000))
|
||||
: 0,
|
||||
recalcStylePerKilochar: renderedCharacterGrowth > 0
|
||||
? round(delta("RecalcStyleCount") / (renderedCharacterGrowth / 1000))
|
||||
: 0,
|
||||
streamSeconds,
|
||||
recordedSeconds: round(elapsedSeconds),
|
||||
nodeStart: Number(before.Nodes ?? 0),
|
||||
|
||||
Reference in New Issue
Block a user