Skip to content

Large active thread lists keep all sidebar rows mounted #1261

Closed

Description

@jshph

Summary

On a long-running self-hosted instance, the web/PWA sidebar keeps every active thread row mounted, including rows far outside the scrollport and when the sidebar is collapsed.

In Chrome I measured:

  • 1,213 active thread links
  • 16,251 DOM elements
  • ~600 MB renderer memory, with a 1.5 GB recorded peak

Collapsing the sidebar changed visibility but did not reduce the mounted tree.

I may simply be keeping more old threads active than the intended workflow. How do established users normally manage older threads? Is regular archiving expected, and is there a recommended way to archive older threads in bulk today beyond per-thread actions or bb environment archive-threads?

If large active lists are expected to remain supported, offscreen containment or sidebar virtualization may help. Related: #1159, #1131, #1205.

Activity

  1. SawyerHood commented on Aug 10, 2026

    @SawyerHood
    Collaborator

    I normally have my agents archive them using the cli!

    But yeah we should virtualize this!

  2. jshph commented on Aug 10, 2026

    @jshph
    ContributorAuthor

    Do you have an automated process with some kind of policy for archiving old threads?

  3. SawyerHood commented on Aug 10, 2026

    @SawyerHood
    Collaborator

    I have a skill that tells a thread to archive itself after a PR is merged

  4. added theissue type on Aug 10, 2026
  5. jshph commented on Aug 10, 2026

    @jshph
    ContributorAuthor

    Here is a more issue-specific, pseudonymized eval that could also serve as an agent prompt:

    Build a reproducible benchmark for sidebar virtualization using a synthetic dataset shaped like a measured real-world bb installation. Do not copy thread names, prompts, repository names, hostnames, or other user content.
    
    Observed baseline to reproduce:
    - approximately 1,200 active, unarchived thread rows;
    - approximately 16,000 total DOM elements;
    - every sidebar thread row remains mounted, including when the sidebar is collapsed;
    - installed Chromium PWA in a narrow window;
    - idle renderer CPU approximately 2.6–4.3%;
    - renderer memory approximately 600 MB, with a previously observed peak around 1.5 GB;
    - CSS shimmer exists but did not appear to explain the dominant cost.
    
    Generate deterministic synthetic threads with the same structural characteristics: realistic nesting depth, parent/child relationships, a mixture of statuses, varied title lengths, and enough active rows to reach roughly 1,200. Include additional 100, 500, and 5,000-row variants only to characterize scaling.
    
    Compare:
    A. current sidebar behavior;
    B. CSS containment using content-visibility;
    C. true row virtualization with a small overscan.
    
    Use the installed-PWA viewport dimensions if they can be detected; otherwise use a documented narrow viewport around 800px wide. Test each build with the sidebar open, collapsed, and hidden by the narrow responsive layout.
    
    After a 15-second settle, capture repeatable Chrome performance traces for:
    1. 60 seconds idle on a thread;
    2. a deterministic top-to-bottom-and-back scroll;
    3. a replay of representative websocket events affecting one active thread.
    
    Run each case five times and report medians for:
    - mounted sidebar rows;
    - total DOM elements;
    - renderer CPU/task time;
    - JS heap and renderer memory;
    - long tasks and dropped frames;
    - click-to-selection latency;
    - requests caused by the replayed realtime events.
    
    Primary success criteria:
    - mounted rows are limited to visible rows plus overscan rather than the full dataset;
    - DOM size remains approximately flat as thread count grows;
    - collapsing or responsively hiding the sidebar does not leave all rows doing render/layout work;
    - idle and realtime renderer CPU are materially below the measured 2.6–4.3% baseline;
    - memory is materially below the approximately 600 MB baseline and remains stable;
    - virtualization does not change realtime request counts or break nesting, selection, keyboard navigation, scroll restoration, or accessibility.
    
    Keep archiving out of the benchmark. The sidebar should remain healthy with thousands of active threads regardless of each users archival policy. Save the fixture generator, trace procedure, raw results, and a short before/after table so another contributor can reproduce the result.
    

    The anonymized measurements above come from the affected installed PWA and are intended as target baselines, rather than generic thresholds.

  6. SawyerHood commented on Aug 10, 2026

    @SawyerHood
    Collaborator

    Confirmed and measured this on a seeded 1,200-thread database (pnpm seed:perf, #1300), mobile viewport (390x844), Chromium.

    Two additions to what's described here:

    • The mobile drawer pays the full render cost on every open, not just once: the drawer unmounts on close, so each open replays the whole list render. With 132 unarchived threads (~21k DOM nodes mounted) each open is a single synchronous long task of ~1.2s at desktop speed and ~5.3s at 4x CPU throttle — i.e. seconds of frozen UI per sidebar tap on a phone. This is very likely the current "mobile app is slow" report.
    • Scroll frame rate inside the open drawer is fine (no frames >50ms); the cost is entirely the initial mount of all rows.

    Repro: pnpm seed:perf on a dev instance, open the app at mobile width, tap the sidebar toggle, close, tap again — watch the long task in the performance panel.

    Suggested approach, in order of impact: virtualize the thread list (fixes both this issue and the mobile case), and keep the mobile drawer mounted (translate off-screen) so reopening doesn't replay the mount.

  7. self-assigned this
    on Aug 10, 2026
  8. added a commit that references this issue on Aug 11, 2026
    1e81d3b
  9. jshph commented on Aug 11, 2026

    @jshph
    ContributorAuthor

    Thanks @SawyerHood !!

  10. added a commit that references this issue on Aug 14, 2026
    6768297
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions