Spaces:
Running
Running
|
Download docs/performance-profile-2571.md from Felladrin/MiniSearch: direct link, hf CLI and curl.
- Browser
- Download file 3.89 kB
-
https://huggingface.co/spaces/Felladrin/MiniSearch/resolve/main/docs/performance-profile-2571.md
- Command line
-
hf download hf://spaces/Felladrin/MiniSearch/docs/performance-profile-2571.md
-
curl -L -o performance-profile-2571.md https://huggingface.co/spaces/Felladrin/MiniSearch/resolve/main/docs/performance-profile-2571.md
3.89 kB
| # Long-task profile: search with AI response and page content | |
| Issue: [#2571](https://github.com/felladrin/MiniSearch/issues/2571) β keep long tasks off the main thread during search and generation. | |
| This is the "recorded before and after" evidence the issue asks for. The measurement harness is | |
| [`e2e/main-thread-budget.spec.ts`](../e2e/main-thread-budget.spec.ts): a `longtask` | |
| `PerformanceObserver` installed with `page.addInitScript` before the app boots, so it sees every | |
| task the app runs, with a streaming window opened when the inference request is issued and closed | |
| once the full answer has rendered. | |
| ## Method | |
| - Production build (`npm run build && HOST=127.0.0.1 PORT=<p> npm run start`), Chromium full | |
| channel β `chrome-headless-shell` never emits `longtask` entries, so it cannot be used for this. | |
| - Everything external is mocked (config, search, page content, and the OpenAI-compatible inference | |
| stream served by a local SSE server), so the numbers are not noisy and no live service is involved. | |
| - `enablePageContentFetch: true`, so the search-to-generation handoff is exercised. | |
| - The profiled answer is an 18.8 kB streamed answer: 70 markdown paragraphs, ~70 inline links and | |
| one JavaScript code block. The size is deliberate β the per-frame cost the issue describes grows | |
| with the answer, so a short answer shows nothing. | |
| - 5 runs per build, alternating, on the same machine. | |
| ## Result | |
| | Build | Long tasks in the streaming window | Total main-thread time blocked | Longest single task | | |
| | --- | --- | --- | --- | | |
| | `main` (before) | 30, 31, 31, 32, 32 | 2008, 2050, 2143, 2149, 2207 ms | 108β186 ms | | |
| | All seven fixes merged (after) | 0, 0, 1, 1, 1 | 0, 0, 51, 52, 52 ms | β€ 52 ms | | |
| Roughly **2.1 seconds of blocking main-thread work per streamed answer is gone**, and the worst | |
| single task drops from ~160β190 ms to at or below the 50 ms long-task reporting threshold β i.e. | |
| after the change there is effectively nothing left to report. | |
| ## What removed what | |
| | Long task on `main` | Removed by | | |
| | --- | --- | | |
| | Full-markdown re-parse on every throttled frame (12 Hz), growing with the answer | `perf/memoized-markdown-blocks` β top-level blocks are memoized, so a frame that only extends the last block re-renders that block | | |
| | Shiki loading from `shiki/bundle/full` for the first code block | `perf/shiki-lazy-language-subset` β web subset, and a language outside it degrades without a load attempt | | |
| | One `resize` listener per citation link, each reading `scrollWidth` and calling `setState` | `perf/shared-resize-observer-citation-links` β one shared `ResizeObserver`, and the expand animates `transform`/`opacity` instead of `width` | | |
| | `gptTokenizer.encode()` over every full page body at the search-to-generation handoff | `perf/page-excerpt-tokenization-worker` β the tokenization runs in a worker, with a synchronous fallback | | |
| | Re-encoding the whole joined candidate per iteration in the rolling summary | `perf/incremental-rolling-summary-tokens` β each part encoded once, running count kept | | |
| ## Reproducing | |
| The committed spec asserts the 200 ms budget on a code-block-free answer, which is the path that | |
| passes on `main` too. To reproduce the table above, widen the answer (paragraphs + links + a code | |
| block), raise the budget so the assertion cannot fail, and read the collected task list against a | |
| `main` build and against the merged branches. | |
| ## Caveats | |
| - Measured on one machine (arm64 Linux, Chromium 153). Absolute numbers move with the hardware; the | |
| before/after gap is large enough that the direction is not in doubt. | |
| - The numbers cover the mocked streaming path. A real deployment adds upstream latency, not | |
| main-thread work, so the main-thread picture is representative. | |
| - `perf/e2e-long-task-budget` is the branch that carries the guard; the seven fixes are the ones | |
| that moved these numbers. | |