perf: reduce streaming render cost and refresh activity page on demand

- Segment streaming Markdown so completed blocks are reused and only the growing tail is re-parsed; fall back to whole-document parsing for document-wide constructs
- Memoize conversation sidebar rows and cache per-conversation derived activity, ordering and pending approvals
- Activity page loads on entry, refreshes every 15 s while visible, and has a single header refresh button
- Include pending settings, model download source, device sharing and knowledge gateway changes in the working tree
- Add Electron streaming input benchmark and regression tests
This commit is contained in:
mesalogo
2026-10-01 21:49:09 +08:00
parent 016f987026
commit c8f327fc4e
75 changed files with 3042 additions and 905 deletions
+46 -4
View File
@@ -86,7 +86,7 @@ async function run() {
for (let round = 0; round < 4; round++) {
render(current.MarkdownRenderer, '')
flushSync(() => originalRoot.render(<UiLocaleProvider initialPreference="en-US">
<original.MarkdownRenderer>{''}</original.MarkdownRenderer>
<original.UnsegmentedMarkdownRenderer>{''}</original.UnsegmentedMarkdownRenderer>
</UiLocaleProvider>))
for (const [index, length] of prefixLengths.entries()) {
const prefix = longAnswerCorpus.slice(0, length)
@@ -98,7 +98,7 @@ async function run() {
const start = performance.now()
if (variant === 'original') {
flushSync(() => originalRoot.render(<UiLocaleProvider initialPreference="en-US">
<original.MarkdownRenderer>{prefix}</original.MarkdownRenderer>
<original.UnsegmentedMarkdownRenderer>{prefix}</original.UnsegmentedMarkdownRenderer>
</UiLocaleProvider>))
void originalHost.offsetHeight
} else {
@@ -119,6 +119,48 @@ async function run() {
flushSync(() => originalRoot.unmount())
originalHost.remove()
}
// Streaming shape: small deltas appended to an already long answer, on
// persistent roots, as ChatTimeline receives them. Alternate variant order.
const deltaSamples = { original: [] as number[], current: [] as number[] }
const deltaHost = document.createElement('div')
deltaHost.className = host.className
deltaHost.style.cssText = host.style.cssText
document.body.append(deltaHost)
const deltaRoot = createRoot(deltaHost)
const deltaStart = Math.floor(longAnswerCorpus.length * 0.8)
const deltaSize = 120
try {
const renderDelta = (variant: 'original' | 'current', prefix: string) => {
if (variant === 'original') {
flushSync(() => deltaRoot.render(<UiLocaleProvider initialPreference="en-US">
<original.UnsegmentedMarkdownRenderer>{prefix}</original.UnsegmentedMarkdownRenderer>
</UiLocaleProvider>))
void deltaHost.offsetHeight
} else {
render(current.MarkdownRenderer, prefix)
void host.offsetHeight
}
}
renderDelta('original', longAnswerCorpus.slice(0, deltaStart))
renderDelta('current', longAnswerCorpus.slice(0, deltaStart))
for (let step = 1; step <= 60; step++) {
const prefix = longAnswerCorpus.slice(0, deltaStart + step * deltaSize)
const order = step % 2 === 0 ? ['original', 'current'] as const : ['current', 'original'] as const
for (const variant of order) {
await new Promise<void>(resolve => requestAnimationFrame(() => resolve()))
const start = performance.now()
renderDelta(variant, prefix)
if (step > 5) deltaSamples[variant].push(performance.now() - start)
}
if (step % 10 === 0 && snapshot() !== snapshot(deltaHost)) throw new Error(`Delta DOM mismatch: ${step}`)
}
} finally {
flushSync(() => deltaRoot.unmount())
deltaHost.remove()
}
const streamingDelta = { startCharacters: deltaStart, deltaCharacters: deltaSize,
samplesPerVariant: deltaSamples.current.length,
wholeDocumentMs: stats(deltaSamples.original), segmentedMs: stats(deltaSamples.current) }
const longAnswer = { characters: longAnswerCorpus.length, bytes: new TextEncoder().encode(longAnswerCorpus).length,
prefixLengths, warmupSweeps: 1, measuredSweeps: 3, samplesPerVariant: longSamples.current.length,
originalRenderMs: stats(longSamples.original), currentRenderMs: stats(longSamples.current),
@@ -131,7 +173,7 @@ async function run() {
if (normalize(prefix) !== originalNormalize(prefix)) throw new Error(`Normalizer mismatch: ${JSON.stringify(prefix)}`)
prefixesChecked++
for (const renderHtml of [false, true]) {
render(original.MarkdownRenderer, prefix, renderHtml)
render(original.UnsegmentedMarkdownRenderer, prefix, renderHtml)
const expected = snapshot()
render(current.MarkdownRenderer, prefix, renderHtml)
if (snapshot() !== expected) throw new Error(`DOM mismatch (${renderHtml}): ${JSON.stringify(prefix)}`)
@@ -143,7 +185,7 @@ async function run() {
if (!host.querySelector('h1') || !host.querySelector('strong') || !host.querySelector('.katex')) {
throw new Error('Real Markdown formatting missing')
}
return { results, longAnswer, prefixesChecked, domChecks }
return { results, longAnswer, streamingDelta, prefixesChecked, domChecks }
}
Object.assign(window, { streamingMarkdown: run })