--- a/apps/mobile/src/features/review/shikiReviewHighlighter.ts +++ b/apps/mobile/src/features/review/shikiReviewHighlighter.ts @@ -211,6 +211,35 @@ function joinPatchLines(lines: ReadonlyArray): string { return lines.map(stripTrailingNewline).join("\n"); +} + +// DIAGNOSTIC BUILD ONLY (never shipped, never in a prod A/B): records each JS slice of highlightLines +// (work since the last resume, wait inside the yield) and logs one summary when the file finishes. +type __T3DiagHl = { start: number; startDate: number; resumedAt: number; batches: number; slices: string[] }; +function __t3diagHlStart(): __T3DiagHl { + const now = performance.now(); + return { start: now, startDate: Date.now(), resumedAt: now, batches: 0, slices: [] }; +} +async function __t3diagHlYield(diag: __T3DiagHl, yieldFn: () => Promise): Promise { + const before = performance.now(); + await yieldFn(); + const after = performance.now(); + diag.slices.push(`${(before - diag.resumedAt).toFixed(1)}/${(after - before).toFixed(1)}/${diag.batches}`); + diag.batches = 0; + diag.resumedAt = after; +} +function __t3diagHlEnd(diag: __T3DiagHl, lines: number, chars: number): void { + const end = performance.now(); + diag.slices.push(`${(end - diag.resumedAt).toFixed(1)}/end/${diag.batches}`); + const work = diag.slices.map((s) => Number(s.split("/")[0])); + const waits = diag.slices.map((s) => s.split("/")[1]).filter((w) => w !== "end").map(Number); + const sum = (xs: number[]) => xs.reduce((a, b) => a + b, 0); + console.log( + `__t3diag hl summary lines=${lines} chars=${chars} slices=${diag.slices.length} total=${(end - diag.start).toFixed(1)}ms totalDate=${Date.now() - diag.startDate}ms work=${sum(work).toFixed(1)} waits=${sum(waits).toFixed(1)} maxWork=${Math.max(...work).toFixed(1)} maxWait=${waits.length ? Math.max(...waits).toFixed(1) : 0}`, + ); + for (let i = 0; i < diag.slices.length; i += 20) { + console.log(`__t3diag hl slices[${i}] ${diag.slices.slice(i, i + 20).join(" ")}`); + } } function waitForNextFrame(): Promise { @@ -512,6 +541,7 @@ const highlighter = await getHighlighter(); const sourceLines = code.split("\n"); + const __t3diag = __t3diagHlStart(); const highlightedLines: Array> = []; const shortLineBatch: string[] = []; @@ -520,6 +550,7 @@ return; } + __t3diag.batches += 1; const tokenLines = highlighter.codeToTokensBase(shortLineBatch.join("\n"), { lang: language, theme, @@ -547,12 +578,13 @@ lineIndex + 1 < sourceLines.length && (shortLineBatch.length === 0 || line.length > REVIEW_TOKENIZE_MAX_LINE_LENGTH) ) { - await waitForNextFrame(); + await __t3diagHlYield(__t3diag, waitForNextFrame); } } await flushShortLineBatch(); + __t3diagHlEnd(__t3diag, sourceLines.length, code.length); return highlightedLines; }