Skip to content

UI refactors of benchmarks v3#7723

Merged
connortsui20 merged 4 commits intoct/benchmarks-v3from
claude/benchmarks-v3-full-history
Apr 29, 2026
Merged

UI refactors of benchmarks v3#7723
connortsui20 merged 4 commits intoct/benchmarks-v3from
claude/benchmarks-v3-full-history

Conversation

@connortsui20
Copy link
Copy Markdown
Contributor

Summary

Fixes the UI of the benchmarks v3 website.

  • no longer max of 1000 commits
  • LTTB dynamic downsampling on the client side
  • a bunch of other stuff

Testing

More snapshot testing.

claude added 3 commits April 29, 2026 16:30
…?n=`

The chart endpoints capped numeric `?n=` values at `MAX_COMMIT_WINDOW =
1000` and the landing page silently fell back to `?n=1000` per chart.
That hid older history from the user — there was no way to see commits
older than the 1000th most-recent regardless of how the chart was
controlled. Drop the clamp:

- `CommitWindow::parse` now floors `?n=0` to `1` and otherwise keeps
  numeric values as-is. `?n=99999` is no longer silently rewritten to
  `?n=1000`.
- HTML route `UiQuery::fetch_window` now defaults to
  `CommitWindow::All`, so the `/`, `/chart/{slug}` and `/group/{slug}`
  pages serve the entire history by default. `?n=` remains as a
  power-user override on the commit window.
- Drop the unused `MAX_COMMIT_WINDOW` constant and the `PER_CHART_FETCH_N`
  shim that pinned the landing page's per-chart fetch to that ceiling.

Tests:
- Rename `commit_window_parse_clamps` → `commit_window_parse_floors_zero_but_keeps_large_values`
  and update its assertion that `Last(99_999)` survives.
- `chart_page_window_caps_commits` gains a `?n=99999` case that confirms
  the clamp is gone.
- New `permalink_pages_inline_full_raw_history` asserts `/chart/{slug}`
  and `/group/{slug}` inline 200 raw commits when seeded that wide.
- New `chart_payload_does_not_carry_raw_commit_count` is a forward
  guard against accidentally re-introducing server-side downsampling
  on the wire.
- `fetch_window_default_is_all` replaces the old `_is_max` test.

Bumps `STATIC_ASSET_VERSION` to `bench-v3-ui-11`; refreshes snapshots
for the asset URL.

This commit on its own keeps the existing client behaviour (chart-init.js
still requests `?n=1000` and does no client-side downsampling), so a
chart with 5000 raw commits in the DB is fetched whole but only the
last 1000 are rendered. The follow-up commits add the dynamic
client-side LTTB pass that bounds the rendered point count.

Signed-off-by: Claude <claude@anthropic.com>
…mit range

Cap the rendered point count per chart at `MAX_VISIBLE_POINTS = 500`,
applied client-side and re-derived from the *currently visible*
commit range on every interaction (slider drag, drag-pan,
drag-rectangle-zoom, wheel-pan, range-strip drag). The common case
(zoomed in to the last ~100 commits) renders raw — no LTTB at all —
while zoomed-out views downsample to the cap with peaks preserved.

Why client-side and chart-wide:
- The previous design fetched a server-LTTB'd 600-point summary once,
  which meant zooming in didn't reveal more detail (the raw data was
  already gone). Doing LTTB on the client lets zoom-in render raw and
  zoom-out downsample.
- The cap is on **unique commit indices shared across all series**,
  not per-series. Per-series LTTB picked different peaks for each
  line and the visible x-position count blew past the cap (a
  9-series chart drew up to 9 × cap distinct x-columns). Now we
  build one virtual series — the per-commit max-y across datasets —
  run LTTB on that, and every series renders at the shared kept
  indices. Series unit/scale are uniform within a Vortex chart, so
  max-y is a faithful proxy for "interesting peaks across any line".

Wire and tooltip:
- The lazy-fetch URL stays `?n=all`. The server returns raw, the
  client decides what to render.
- Chart.js interaction mode flips from `"index"` to `"x"` so the
  tooltip snaps to the nearest commit *with rendered data* rather
  than to the cursor's exact index. After LTTB most indices are null
  in `dataset.data` (`spanGaps: true` connects across), and `"index"`
  mode would happily pick a null one and show an empty popup. `"x"`
  reads `dataPoints[0].dataIndex` from a real non-null index, so the
  external handler / crosshair plugin / onClick PR-link path keep
  working unchanged.

Slider sync:
- A new `syncSliderFromRange` helper inside `rebuildVisibleAndUpdate`
  centralises the toolbar's "Show" slider write. Every visible-range
  change — slider drag, drag-pan, drag-rectangle-zoom, wheel-pan,
  range-strip drag — flows through one function and the slider
  readout stays truthful. Programmatic `slider.value` writes don't
  fire `input`, so this never re-enters `applyScope`.

UX:
- Badge slot rendered in every `chart-card-title` and `/chart` page
  meta line, hidden by default; JS flips it on with
  `downsampled · keptCommits / visibleCommits` when LTTB is active.
  Both numbers are commit counts (not point counts summed across
  series), so the denominator matches the slider's mental model.
  Title tooltip explains LTTB and points users at "zoom in past
  MAX_VISIBLE_POINTS to see every raw measurement".
- `pointHitRadius: 8` retained; the cap means there's plenty of
  empty x-space between rendered points, but `mode: "x"` handles the
  inter-point hover case.
- Static slider markup drops `max="1000"` for `max="100"`/`step="1"`
  placeholders that `chart-init.js` rewrites from the loaded
  commit count.

Bumps `STATIC_ASSET_VERSION` to `bench-v3-ui-12`; refreshes snapshots
for the new badge slot, slider markup, and JS hash.

Signed-off-by: Claude <claude@anthropic.com>
…g page

The landing page used to auto-expand the first group's
`<details>` (Random Access in canonical order). Drop the `open`
attribute so every group renders collapsed and the user picks which
to expand. The first group's chart payloads stay inlined in the HTML
— so opening it still hydrates without a network round-trip — but
the disclosure itself is now the user's choice.

Side fix to keep the inline-payload optimisation working:
`fetchAndConstruct` was checking `canvas.__bench_payload`, which is
only set inside `constructChart`, so on a fresh page load every
expand triggered a network fetch even when JSON was inlined. Switch
to "try `constructChart` synchronously first; only fetch if it
returns null", which reads inline JSON via `readInlinePayload` and
short-circuits the fetch.

Tests:
- `details_first_group_open_others_closed` →
  `details_all_groups_closed_by_default`. Asserts every disclosure is
  closed and that the first group's chart payload is still inlined
  (so the on-toggle hydration is fast).

Bumps `STATIC_ASSET_VERSION` to `bench-v3-ui-13`; refreshes snapshots
for the dropped `open` attribute and the JS asset URL.

Signed-off-by: Claude <claude@anthropic.com>
@connortsui20 connortsui20 added the changelog/skip Do not list PR in the changelog label Apr 29, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 29, 2026

Merging this PR will improve performance by 10.39%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 1129 untouched benchmarks
⏩ 68 skipped benchmarks1
🗄️ 33 archived benchmarks run2

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation new_bp_prim_test_between[i16, 32768] 133.8 µs 121.2 µs +10.39%

Comparing claude/benchmarks-v3-full-history (e9819a9) with ct/benchmarks-v3 (87a51c1)

Open in CodSpeed

Footnotes

  1. 68 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. 33 benchmarks were run, but are now archived. If they were deleted in another branch, consider rebasing to remove them from the report. Instead if they were added back, click here to restore them.

…decessor

Two bugs in the tooltip after LTTB downsampling:

1. Hovering between two LTTB-kept points showed stats for *both*
   commits. `mode: "x"` returns every dataset element whose
   `pointHitRadius` (8px) overlaps the cursor, and on a chart with
   ~500 columns spread over ~600px the kept points sit ~1.2px apart,
   so a cursor between two columns intersects both — the rendered
   tooltip got rows for series A at column X *and* column Y, which
   reads as duplicate / mixed data.

2. The per-series `±X.0%` label was wrong. The previous attempt at
   "compare against the previous commit" walked toward higher indices
   in `rawData`. But the SQL is `ORDER BY c.timestamp` ASC, so
   higher index = newer commit, i.e. the chronological *successor*,
   not the predecessor. Walk in the other direction.

Both fixes:

- `interaction.mode` flips from `"x"` to `"nearest"` (with
  `axis: "x"`, `intersect: false`). That returns exactly one closest
  data point regardless of column packing, so `tt.dataPoints[0].dataIndex`
  is unambiguously the single hovered commit.
- The external tooltip handler stops mapping over `tt.dataPoints` and
  iterates `chart.data.datasets` itself, building one row per series at
  the chosen commit (skipping hidden datasets and ones with null
  `rawData[idx]`). One row per series, period.
- Each row's predecessor walk now goes `idx - 1, idx - 2, …` —
  toward the chronologically earlier commit — and the `(current -
  predecessor) / predecessor` direction matches what users read
  as "this commit changed by X% from the one before it".
- Drop the now-dead `tooltip.itemSort` config; the handler sorts
  rows itself by current y-value descending so the top-to-bottom
  order matches the visual stack of lines at the hovered x.
- Refuse to flash an empty popup: if every series was hidden or
  null at this commit, set `host.style.opacity = "0"` and bail.

Bumps `STATIC_ASSET_VERSION` to `bench-v3-ui-15`; refreshes
snapshots for the JS asset URL only — no markup change.

Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
@connortsui20 connortsui20 force-pushed the claude/benchmarks-v3-full-history branch from 1bfa33c to e9819a9 Compare April 29, 2026 20:56
@connortsui20 connortsui20 merged commit 6444858 into ct/benchmarks-v3 Apr 29, 2026
57 of 58 checks passed
@connortsui20 connortsui20 deleted the claude/benchmarks-v3-full-history branch April 29, 2026 21:04
connortsui20 added a commit that referenced this pull request Apr 29, 2026
## Summary

Fixes the UI of the benchmarks v3 website.

- no longer max of 1000 commits
- LTTB dynamic downsampling on the client side
- a bunch of other stuff

## Testing

More snapshot testing.

---------

Signed-off-by: Claude <claude@anthropic.com>
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
Co-authored-by: Claude <claude@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/skip Do not list PR in the changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants