Skip to content

perf(metrics): keep unchanged metric panels stable when another panel changes - #128357

Merged
JoshuaKGoldberg merged 9 commits into
joshgoldberg/logs-1035-reduce-lag-when-expanding-or-collapsing-metricsfrom
joshgoldberg/logs-1035-functional-metric-query-setters
Oct 22, 2026
Merged

JoshuaKGoldberg merged 9 commits into
joshgoldberg/logs-1035-reduce-lag-when-expanding-or-collapsing-metricsfrom
joshgoldberg/logs-1035-functional-metric-query-setters

Conversation

@JoshuaKGoldberg

@JoshuaKGoldberg JoshuaKGoldberg commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Unchanged metric panels now keep the same query params and mutators when another panel changes, because row mutators hand updater functions to setQueries instead of closing over the rendered queries.

This is done by:

  • Switching row mutator updater functions to setQueries
  • Moving the URL-backed provider onto nuqs and its nice stable setter
  • Binding each row's mutators to a stable row id, so a mutator held across another row's removal still edits its own row
  • Resetting nuqs's global URL update queue between tests in the shared test adapter

Rapid edits now coalesce into a single history entry, since nuqs batches URL writes.

Split out of #126977 so we don't have to use esoteric React hooks. Thanks for prodding me on the docs @nsdeschenes 😄

@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Oct 21, 2026
@sentry

sentry Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Sentry Snapshot Testing

Name Added Removed Changed Renamed Unchanged Skipped Status
sentry-frontend
sentry-frontend
0 0 0 0 754 0 ✅ Unchanged

⚙️ sentry-frontend Snapshot Settings

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

📊 Type Coverage Diff

Metric Before After Delta
Coverage 95.77% 95.77% ±0%
Typed 141,382 141,421 🟢 +39
Untyped 6,247 6,249 🔴 +2
🔍 2 new type safety issues introduced

Non-null assertions (!) (2 new)

File Line Detail
static/app/views/explore/metrics/multiMetricsQueryParams.tsx 117 decodedMetricQueries.keys().next().value!
static/app/views/explore/metrics/useMetricQueriesController.tsx 221 rowMutators[i]!

This is informational only and does not block the PR.

@linear-code

linear-code Bot commented Oct 21, 2026

Copy link
Copy Markdown

LOGS-1035

… changes

Row mutators hand updater functions to setQueries instead of closing over the rendered queries, and decoded queries are cached per URL value and index, so unchanged panels keep the same query params and mutators. The URL-backed provider moves onto nuqs, whose setter is stable and composes queued writes.
@JoshuaKGoldberg
JoshuaKGoldberg force-pushed the joshgoldberg/logs-1035-functional-metric-query-setters branch from 3de35e2 to f512f71 Compare October 21, 2026 15:34
@JoshuaKGoldberg JoshuaKGoldberg changed the title ref(metrics): Replace the latest-queries ref with updater-based setters perf(metrics): Keep unchanged metric panels stable when another panel changes Oct 21, 2026
…lapsing-metrics' into joshgoldberg/logs-1035-functional-metric-query-setters
@JoshuaKGoldberg JoshuaKGoldberg changed the title perf(metrics): Keep unchanged metric panels stable when another panel changes perf(metrics): keep unchanged metric panels stable when another panel changes Oct 21, 2026
…lapsing-metrics' into joshgoldberg/logs-1035-functional-metric-query-setters
Index-bound mutators edited the wrong row when captured before an earlier row was removed. Adds coverage for unrelated URL changes, no-op writes, and history pushes.
Labels can repeat after an external navigation that keeps the row count, so mutators resolved by label could edit or remove the wrong row.
nuqs only tracks its own writes after the provider's effects subscribe, so a second write during the mount commit started from the stale URL and dropped the first.
Also keeps the useStableLabels docblock attached to the hook.
// nuqs keeps its URL update queue in a global, and only its own testing
// adapter clears it on mount, so a previous test's pending write would
// otherwise become this test's initial state. The inner provider overrides
// its adapter.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Question] Is this, like, a known nuqs thing? It confused me at first, which is why I didn't delete this AI-y comment the way I normally do...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrrm, this may be a bigger question for @TkDodo

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 184ec89. Configure here.

@nsdeschenes nsdeschenes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things look good to me, but worth taking a peek at those cursor comments.

…order

Adding and reordering panels now write through updater functions, so they no longer overwrite row edits that haven't been applied yet. Row mutators are cached per row id, and the decode cache evicts least recently used entries keyed by value occurrence, so panels that only shift position keep their identity.

Refs LOGS-1035
@JoshuaKGoldberg
JoshuaKGoldberg merged commit 59d7274 into joshgoldberg/logs-1035-reduce-lag-when-expanding-or-collapsing-metrics Oct 22, 2026
77 of 78 checks passed
@JoshuaKGoldberg
JoshuaKGoldberg deleted the joshgoldberg/logs-1035-functional-metric-query-setters branch October 22, 2026 16:18
JoshuaKGoldberg added a commit that referenced this pull request Oct 29, 2026
…es (#126977)

Problem: Expanding or collapsing a metric panel writes to the URL. Every
panel re-decoded its query params from the URL, and table rows and cells
subscribed to the location for their links. So any expansion/collapse ->
causes a URL change -> causes every component in every other panel to
re-render.

This PR fixes it with a few things:

* Sample rows only read the location in their trace link cell, and
Explore field cells keep their cell action menus out of location-driven
re-renders.
* Embedded sample tables keep their rows memoized even when their query
is disabled.
* Button tracking also returns a stable function

As part of this I extracted `renderTraceCell` out into a `TraceLinkCell`
component.

Keeping unchanged panels' query params and mutators stable is split out
into #128357.

Together with getsentry/sentry-javascript#25336
I think this should fix much of the perf issues around metrics panel
toggles.

| Collapsing one of three metric panels (median of 12) | Prod | This
PR's preview | Delta |
| --- | --- | --- | --- |
| Main-thread busy time | 159ms | 128ms | −20% |
| Components re-rendered | 9,894 | 1,839 | −81% |
| React commits | 7 | 4 | −43% |

Closes LOGS-1035.

This branch was successfully deployed

1 active deployment
Preview — 0d4b7b22 Deployed Oct 22, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants