perf(frontend): split chat streaming, load Inter, isolate admin CSS
Independent Staging Quality Gate / validate (push) Successful in 10m14s
Independent Staging Quality Gate / publish (push) Successful in 11m5s

Settled messages no longer rebuild on every token, Inter is actually
requested, and admin routes drop the 33 KB chat stylesheet. Root
force-dynamic is gone so public shells can prerender without changing
the no-store Cache-Control contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-08-29 03:39:43 +08:00
co-authored by Cursor
parent bf697d71a2
commit 3198fb6b2b
41 changed files with 1528 additions and 307 deletions
@@ -0,0 +1,109 @@
{
"generatedAt": "2026-08-28T19:24:57.446Z",
"replyChars": 916,
"empty": {
"run1": {
"name": "empty-unsplit-1",
"tokens": 46,
"elapsedMs": 1.7442499999999654,
"probe": {
"settledListRenders": 0,
"settledRowRenders": 92,
"streamingRowRenders": 46,
"unsplitListRenders": 46
}
},
"run2": {
"name": "empty-unsplit-2",
"tokens": 46,
"elapsedMs": 2.1559169999999312,
"probe": {
"settledListRenders": 0,
"settledRowRenders": 92,
"streamingRowRenders": 46,
"unsplitListRenders": 46
}
},
"unsplit": {
"name": "empty-unsplit-1",
"tokens": 46,
"elapsedMs": 1.7442499999999654,
"probe": {
"settledListRenders": 0,
"settledRowRenders": 92,
"streamingRowRenders": 46,
"unsplitListRenders": 46
}
},
"split": {
"name": "empty-split",
"tokens": 46,
"elapsedMs": 1.5974159999999529,
"probe": {
"settledListRenders": 1,
"settledRowRenders": 1,
"streamingRowRenders": 46,
"unsplitListRenders": 0
}
}
},
"long": {
"run1": {
"name": "long-unsplit-1",
"tokens": 46,
"elapsedMs": 155.65337499999998,
"probe": {
"settledListRenders": 0,
"settledRowRenders": 1932,
"streamingRowRenders": 46,
"unsplitListRenders": 46
}
},
"run2": {
"name": "long-unsplit-2",
"tokens": 46,
"elapsedMs": 147.32045800000003,
"probe": {
"settledListRenders": 0,
"settledRowRenders": 1932,
"streamingRowRenders": 46,
"unsplitListRenders": 46
}
},
"unsplit": {
"name": "long-unsplit-1",
"tokens": 46,
"elapsedMs": 155.65337499999998,
"probe": {
"settledListRenders": 0,
"settledRowRenders": 1932,
"streamingRowRenders": 46,
"unsplitListRenders": 46
}
},
"split": {
"name": "long-split",
"tokens": 46,
"elapsedMs": 4.582125000000019,
"probe": {
"settledListRenders": 1,
"settledRowRenders": 41,
"streamingRowRenders": 46,
"unsplitListRenders": 0
}
}
},
"variance": {
"emptyElapsed": 0.23601375949547024,
"longElapsed": 0.053535087176875884,
"emptyUnsplitRenders": 0,
"longUnsplitRenders": 0
},
"splitGain": {
"emptyElapsed": 0.18084738422739577,
"longElapsed": 0.9697523383149724,
"longSettledListRenders": 1
},
"usable": true,
"notes": "renderToString always walks the tree, so this measures the split architecture (settled list once + streaming row per token) rather than React.memo itself. Reverse verification is runUnsplit vs runSplitArchitecture."
}