Skip to content

perf(ui): lazily render the alert list with Html.Lazy and Html.Keyed#5357

Open
wbh1 wants to merge 2 commits into
prometheus:mainfrom
wbh1:worktree-ui-alertlist-lazy-rendering
Open

perf(ui): lazily render the alert list with Html.Lazy and Html.Keyed#5357
wbh1 wants to merge 2 commits into
prometheus:mainfrom
wbh1:worktree-ui-alertlist-lazy-rendering

Conversation

@wbh1

@wbh1 wbh1 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

The /alerts view rebuilt and re-diffed the entire alert-group tree on every model update, so interactions such as typing in the filter bar were sluggish when many alerts (10K+) were loaded.

This wraps the alert-group rendering in lazy4 so it is skipped while its inputs are unchanged, and render the group and alert lists with Html.Keyed keyed by group identity and alert fingerprint so list diffs are matched by identity rather than position.

It's similar to what is done for listing silences here.

Now, even though loading a 30MB+ response of all alerts is still slow on first load, typing in the filter box is at least responsive.

Pull Request Checklist

Please check all the applicable boxes.

  • Please list all open issue(s) discussed with maintainers related to this change
  • Is this a new Receiver integration?
    • No
  • Is this a bugfix?
    • No
  • Is this a new feature?
    • No
  • Does this change affect performance?
    • I have provided benchmarks comparison that shows performance is improved or is not degraded
      • I'm not sure how to benchmark the frontend?
    • I have added new benchmarks if required or requested by maintainers
  • Is this a breaking change?
    • My changes do not break the existing cluster messages
    • My changes do not break the existing api
  • I have added/updated the required documentation
  • I have signed-off my commits
  • I will follow best practices for contributing to this project

Which user-facing changes does this PR introduce?

[PERF] Improve responsiveness of UI when loading thousands of alerts

The /alerts view rebuilt and re-diffed the entire alert-group tree on
every model update, so interactions such as typing in the filter bar
were sluggish when many alerts were loaded. Wrap the alert-group
rendering in lazy4 so it is skipped while its inputs are unchanged, and
render the group and alert lists with Html.Keyed keyed by group identity
and alert fingerprint so list diffs are matched by identity rather than
position.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Will Hegedus <whegedus@akamai.com>
@wbh1 wbh1 requested a review from a team as a code owner July 2, 2026 02:17
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 08be9325-0487-46ae-840f-576fd2165f82

📥 Commits

Reviewing files that changed from the base of the PR and between a63b871 and 526506d.

📒 Files selected for processing (1)
  • ui/app/src/Views/AlertList/Views.elm

📝 Walkthrough

Walkthrough

The Elm alert list view now memoizes the alert-groups section with Html.Lazy.lazy4 and renders alerts inside each group with keyed list items using Html.Keyed.ul.

Changes

Keyed/Lazy Rendering Optimization

Layer / File(s) Summary
Imports and lazy view wrapper
ui/app/src/Views/AlertList/Views.elm
Adds Html.Keyed and Html.Lazy.lazy4 imports; view now routes alert groups through a memoized alertGroupsView wrapper.
Keyed alert list items
ui/app/src/Views/AlertList/Views.elm
alertGroup renders alerts with Html.Keyed.ul keyed by alert.fingerprint and passes each alert into AlertView.view.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: performance-focused lazy and keyed rendering of the alert list.
Description check ✅ Passed The description is mostly complete and matches the template, with summary, issue reference, checklist, and release notes filled in; the benchmark item is the main gap.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@TheMeier

TheMeier commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

@wbh1 thank you for contributing.

I am wondering if this might just resurface the issue as discussed in #3817 that there is no real unique and stable groupKey and constructing one here from receiver-name and labels might be a bad choice.

The v2 API can return two alert groups with an identical (receiver,
labels) pair when sibling routes share a receiver and group_by but
differ only by time intervals, so the group key derived from those
fields is not guaranteed unique. Html.Keyed requires keys to be unique
among siblings, so the collision could mis-associate DOM nodes.

Render the group list with plain indexedMap again. The lazy4 wrapper
still skips re-rendering while inputs are unchanged, and the alert list
stays keyed by fingerprint, which is unique within a group.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Will Hegedus <whegedus@akamai.com>
@wbh1

wbh1 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

I am wondering if this might just resurface the issue as discussed in #3817 that there is no real unique and stable groupKey and constructing one here from receiver-name and labels might be a bad choice.

Thanks @TheMeier! Good point.

I dropped the group-level Html.Keyed rendering and gone back to plain positional rendering there.

The main tweak that affects performance (the lazy4 wrapper that skips re-rendering the whole alert-group tree while its inputs are unchanged) is unchanged since that's what actually addresses the filter-bar lag I'm trying to fix here.

I also kept keyed rendering on the per-group alert list since fingerprint is unique within a group but can drop that if you'd prefer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants