Skip to content

perf(editor): avoid unnecessary Set allocations in notVisibleShapes#7837

Merged
steveruizok merged 1 commit intoperformance-stack-1from
sr/perf-not-visible-shapes
Feb 4, 2026
Merged

perf(editor): avoid unnecessary Set allocations in notVisibleShapes#7837
steveruizok merged 1 commit intoperformance-stack-1from
sr/perf-not-visible-shapes

Conversation

@steveruizok
Copy link
Copy Markdown
Collaborator

@steveruizok steveruizok commented Feb 4, 2026

Summary

  • Add fast path when all shapes are visible (return cached empty set)
  • On first run, compute from scratch
  • On subsequent runs, check if result differs before creating new Set
  • Only allocate new Set when contents actually changed

This reduces GC pressure by avoiding unnecessary Set allocations on every frame.

Test plan

  • Typecheck passes
  • Manual testing with many shapes on canvas

🤖 Generated with Claude Code


Note

Low Risk
Low risk performance refactor limited to notVisibleShapes derivation; main risk is subtle cache/identity behavior affecting downstream consumers if the computed value no longer updates when expected.

Overview
Optimizes notVisibleShapes to reduce GC pressure by reusing Set instances instead of allocating a new Set every recompute.

Adds a fast path that returns a cached empty Set when all shapes are visible, computes from scratch on the first run, and on subsequent runs scans to detect changes before building a new Set (returning prevValue when contents are unchanged).

Written by Cursor Bugbot for commit e74207f. This will update automatically on new commits. Configure here.

Optimize the notVisibleShapes derivation to reduce GC pressure:

- Add fast path when all shapes are visible (return cached empty set)
- On first run, compute from scratch
- On subsequent runs, check if result differs before creating new Set
- Only allocate new Set when contents actually changed

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@vercel
Copy link
Copy Markdown

vercel bot commented Feb 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
examples Ready Ready Preview Feb 4, 2026 5:23pm
5 Skipped Deployments
Project Deployment Actions Updated (UTC)
analytics Ignored Ignored Preview Feb 4, 2026 5:23pm
chat-template Ignored Ignored Preview Feb 4, 2026 5:23pm
tldraw-docs Ignored Ignored Preview Feb 4, 2026 5:23pm
tldraw-shader Ignored Ignored Preview Feb 4, 2026 5:23pm
workflow-template Ignored Ignored Preview Feb 4, 2026 5:23pm

Request Review

Copy link
Copy Markdown

@cursor cursor bot left a comment

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.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

return emptySet
}
return prevValue
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shared empty set can be corrupted

Medium Severity

The fast path returns a shared mutable emptySet. Because getNotVisibleShapes() is public and returns the same Set instance, any external mutation of that set can persist across recomputations and cause incorrect culling results later (including after toggling between empty/non-empty states).

Fix in Cursor Fix in Web

return emptySet
}
return prevValue
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All-visible shortcut relies on size equality

Low Severity

The “all shapes visible” fast path uses visibleIds.size === allShapeIds.size as a proxy for set equality. If getShapeIdsInsideBounds ever returns ids outside allShapeIds (e.g., stale spatial index), this can return an empty result even when some current-page shapes are outside the viewport.

Fix in Cursor Fix in Web

@steveruizok steveruizok changed the base branch from main to performance-stack-1 February 4, 2026 17:50
@steveruizok steveruizok merged commit 9da8193 into performance-stack-1 Feb 4, 2026
17 of 18 checks passed
@steveruizok steveruizok deleted the sr/perf-not-visible-shapes branch February 4, 2026 17:51
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.

1 participant