Skip to content

perf: virtualize FormDropdownMenu to reduce DOM nodes and image requests#8476

Open
christian-byrne wants to merge 13 commits intomainfrom
perf/image-dropdown-assets-perf
Open

perf: virtualize FormDropdownMenu to reduce DOM nodes and image requests#8476
christian-byrne wants to merge 13 commits intomainfrom
perf/image-dropdown-assets-perf

Conversation

@christian-byrne
Copy link
Contributor

@christian-byrne christian-byrne commented Jan 30, 2026

Summary

Virtualize the FormDropdownMenu to only render visible items, fixing slow dropdown performance on cloud.

Changes

  • Integrate VirtualGrid into FormDropdownMenu for virtualized rendering
  • Add computed properties for grid configuration per layout mode (grid/list/list-small)
  • Extend VirtualGrid slot to provide original item index for O(1) lookups
  • Change container from max-h-[640px] to fixed h-[640px] for proper virtualization

Review Focus

  • VirtualGrid integration within the popover context
  • Layout mode switching with :key="layoutMode" to force re-render
  • Grid style computed properties match original Tailwind classes

┆Issue is synchronized with this Notion page by Unito

Summary by CodeRabbit

  • New Features

    • Dropdown menus now render via a virtualized grid/list with stable item indexes and responsive row/column sizing.
  • Bug Fixes

    • Improved spacer and scroll calculations and more reliable item-size measurement to reduce layout shifts and rendering glitches.
  • Style

    • Unified item styling, hover/background behavior; images simplified to standard img rendering.
  • Tests

    • Added tests covering virtualization, index propagation, layout modes, dynamic updates, and empty-state handling.

- Integrate VirtualGrid into FormDropdownMenu for virtualized rendering
- Only render visible items (~20-30) instead of all items (100+)
- Add computed properties for grid configuration per layout mode
- Extend VirtualGrid slot to provide original item index
- Change container from max-h to fixed h for proper virtualization

Amp-Thread-ID: https://ampcode.com/threads/T-019c0ca8-be8d-770e-ab31-349937cd2acf
Co-authored-by: Amp <amp@ampcode.com>
@christian-byrne christian-byrne requested a review from a team as a code owner January 30, 2026 05:03
@christian-byrne christian-byrne self-assigned this Jan 30, 2026
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jan 30, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

Replaced direct grid rendering with a measured, virtualized VirtualGrid used by FormDropdownMenu; exposed item indices to slots, added size measurement and resize cleanup in VirtualGrid, updated dropdown item image/styling, and added unit tests for virtualization and dropdown behavior.

Changes

Cohort / File(s) Summary
VirtualGrid core
src/components/common/VirtualGrid.vue
Expose index in v-for="(item, i) in renderedItems", pass slot { item, index }, convert updateItemSize to declared function, preserve debounce/resize logic and add onBeforeUnmount cleanup; adjust spacer/top/bottom spacer calculations and related expressions.
VirtualGrid tests
src/components/common/VirtualGrid.test.ts
New deterministic test suite mocking @vueuse/core (useElementSize/useScroll) to validate visible-range rendering, slot index sequencing, grid columns/maxColumns behavior, empty-state, and dynamic updates.
FormDropdownMenu (renderer)
src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
Refactored to render items via VirtualGrid: added LayoutConfig/LAYOUT_CONFIGS, computed layoutConfig and gridStyle, map items to virtualItems with stable key, destructure props, and switch template to use VirtualGrid while preserving empty-state handling.
FormDropdownMenu tests
src/renderer/.../FormDropdownMenu.test.ts
New tests verifying empty-state rendering, that VirtualGrid is rendered when items exist, items are mapped with key, and layout-mode-specific props (maxColumns/defaultItemHeight) are passed through.
FormDropdownMenuItem
src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuItem.vue
Replaced LazyImage with standard <img draggable="false">, consolidated transition/background classes, and adjusted layout-specific class composition for grid, list, and list-small modes; no API changes.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant Menu as FormDropdownMenu
    participant Grid as VirtualGrid
    participant Viewport as Viewport
    participant ItemComp as FormDropdownMenuItem

    User->>Menu: open dropdown with items
    Menu->>Menu: compute layoutConfig & gridStyle, map items to virtualItems (with keys)
    Menu->>Grid: provide virtualItems, layoutConfig, dimensions
    Grid->>Viewport: measure container size & scroll (useElementSize, useScroll)
    Viewport-->>Grid: provide element sizes and scroll offsets
    Grid->>Grid: calculate visible range (start/end) and spacer heights
    Grid->>ItemComp: render visible items with props { item, index }
    User->>ItemComp: interact (hover/click)
    ItemComp->>Menu: emit selection event (item, index)
    Menu-->>User: handle selection
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

"I hopped through rows to count each stride,
sized every column where numbers hide.
Keys kept steady, slots show new light,
spacers stretch tall and render just right.
A cheerful grid — hop, take flight! 🐇"

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main performance improvement: virtualizing FormDropdownMenu to reduce DOM nodes and image requests.
Description check ✅ Passed The description includes all required template sections: Summary, Changes with detailed What/Breaking/Dependencies coverage, and Review Focus with critical design considerations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch perf/image-dropdown-assets-perf

Important

Action Needed: IP Allowlist Update

If your organization protects your Git platform with IP whitelisting, please add the new CodeRabbit IP address to your allowlist:

  • 136.113.208.247/32 (new)
  • 34.170.211.100/32
  • 35.222.179.152/32

Reviews will stop working after February 8, 2026 if the new IP is not added to your allowlist.


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

@github-actions
Copy link

github-actions bot commented Jan 30, 2026

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 02/04/2026, 12:20:27 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Jan 30, 2026

🎭 Playwright Tests: ✅ Passed

Results: 508 passed, 0 failed, 0 flaky, 8 skipped (Total: 516)

📊 Browser Reports
  • chromium: View Report (✅ 496 / ❌ 0 / ⚠️ 0 / ⏭️ 8)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 9 / ❌ 0 / ⚠️ 0 / ⏭️ 0)

@github-actions
Copy link

github-actions bot commented Jan 30, 2026

Bundle Size Report

Summary

  • Raw size: 20.2 MB baseline 20.2 MB — 🔴 +296 B
  • Gzip: 4.32 MB baseline 4.32 MB — 🟢 -34 B
  • Brotli: 3.34 MB baseline 3.34 MB — 🔴 +27 B
  • Bundles: 233 current • 233 baseline • 108 added / 108 removed

Category Glance
Other 🟢 -11.7 kB (7.07 MB) · Graph Workspace 🔴 +8.24 kB (846 kB) · UI Components 🔴 +3.72 kB (41.5 kB) · Data & Services 🔴 +54 B (2.1 MB) · App Entry Points 🔴 +6 B (22.5 kB) · Vendor & Third-Party ⚪ 0 B (9.37 MB) · + 5 more

Per-category breakdown
App Entry Points — 22.5 kB (baseline 22.5 kB) • 🔴 +6 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-BPlrlZf7.js (new) 22.5 kB 🔴 +22.5 kB 🔴 +7.19 kB 🔴 +6.24 kB
assets/index-B1eQcg7r.js (removed) 22.5 kB 🟢 -22.5 kB 🟢 -7.18 kB 🟢 -6.26 kB

Status: 1 added / 1 removed

Graph Workspace — 846 kB (baseline 838 kB) • 🔴 +8.24 kB

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-Xk7_npXt.js (new) 846 kB 🔴 +846 kB 🔴 +182 kB 🔴 +139 kB
assets/GraphView-B4PeWUCs.js (removed) 838 kB 🟢 -838 kB 🟢 -180 kB 🟢 -137 kB

Status: 1 added / 1 removed

Views & Navigation — 69 kB (baseline 69 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/CloudSurveyView-7_aRb7oB.js (new) 15.8 kB 🔴 +15.8 kB 🔴 +3.46 kB 🔴 +2.94 kB
assets/CloudSurveyView-CT2hviZk.js (removed) 15.8 kB 🟢 -15.8 kB 🟢 -3.46 kB 🟢 -2.95 kB
assets/CloudLoginView-_GqGV75c.js (new) 10 kB 🔴 +10 kB 🔴 +2.93 kB 🔴 +2.58 kB
assets/CloudLoginView-qkoSWM8M.js (removed) 10 kB 🟢 -10 kB 🟢 -2.93 kB 🟢 -2.57 kB
assets/UserCheckView-BaR0ytz4.js (new) 8.39 kB 🔴 +8.39 kB 🔴 +2.23 kB 🔴 +1.94 kB
assets/UserCheckView-D0Ww2GW8.js (removed) 8.39 kB 🟢 -8.39 kB 🟢 -2.23 kB 🟢 -1.94 kB
assets/CloudSignupView-aCTkzXiP.js (new) 7.38 kB 🔴 +7.38 kB 🔴 +2.31 kB 🔴 +2.02 kB
assets/CloudSignupView-BTj1zFuV.js (removed) 7.38 kB 🟢 -7.38 kB 🟢 -2.31 kB 🟢 -2.01 kB
assets/CloudLayoutView-DcWHVqRR.js (removed) 6.43 kB 🟢 -6.43 kB 🟢 -2.12 kB 🟢 -1.83 kB
assets/CloudLayoutView-DR86W7SR.js (new) 6.43 kB 🔴 +6.43 kB 🔴 +2.12 kB 🔴 +1.83 kB
assets/CloudForgotPasswordView-CMqPxTji.js (removed) 5.56 kB 🟢 -5.56 kB 🟢 -1.93 kB 🟢 -1.7 kB
assets/CloudForgotPasswordView-DGuf3gx8.js (new) 5.56 kB 🔴 +5.56 kB 🔴 +1.94 kB 🔴 +1.71 kB
assets/CloudAuthTimeoutView-7U5eC7F_.js (removed) 4.91 kB 🟢 -4.91 kB 🟢 -1.77 kB 🟢 -1.55 kB
assets/CloudAuthTimeoutView-DNu7gMc-.js (new) 4.91 kB 🔴 +4.91 kB 🔴 +1.77 kB 🔴 +1.55 kB
assets/CloudSubscriptionRedirectView-CEY-1rqF.js (removed) 4.71 kB 🟢 -4.71 kB 🟢 -1.77 kB 🟢 -1.57 kB
assets/CloudSubscriptionRedirectView-jJ2lzzHv.js (new) 4.71 kB 🔴 +4.71 kB 🔴 +1.77 kB 🔴 +1.56 kB
assets/UserSelectView-BVqTqWLQ.js (new) 4.49 kB 🔴 +4.49 kB 🔴 +1.64 kB 🔴 +1.47 kB
assets/UserSelectView-BXlTyN_Z.js (removed) 4.49 kB 🟢 -4.49 kB 🟢 -1.64 kB 🟢 -1.47 kB
assets/CloudSorryContactSupportView-BPXBOTez.js 1.02 kB 1.02 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/layout-ncetNFDR.js 296 B 296 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 9 added / 9 removed

Panels & Settings — 410 kB (baseline 410 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/WorkspacePanel-BpgYEaOL.js (new) 26.9 kB 🔴 +26.9 kB 🔴 +5.66 kB 🔴 +4.98 kB
assets/WorkspacePanel-Dx8mEf01.js (removed) 26.9 kB 🟢 -26.9 kB 🟢 -5.65 kB 🟢 -4.97 kB
assets/SecretsPanel-CfyGAJ4f.js (new) 21.5 kB 🔴 +21.5 kB 🔴 +5.28 kB 🔴 +4.64 kB
assets/SecretsPanel-n37moPEu.js (removed) 21.5 kB 🟢 -21.5 kB 🟢 -5.27 kB 🟢 -4.63 kB
assets/LegacyCreditsPanel-BqHiu-wK.js (removed) 20.8 kB 🟢 -20.8 kB 🟢 -5.62 kB 🟢 -4.93 kB
assets/LegacyCreditsPanel-C8NsT0Ag.js (new) 20.8 kB 🔴 +20.8 kB 🔴 +5.62 kB 🔴 +4.93 kB
assets/SubscriptionPanel-Bq16IX7y.js (removed) 18.8 kB 🟢 -18.8 kB 🟢 -4.76 kB 🟢 -4.2 kB
assets/SubscriptionPanel-D5at3kWJ.js (new) 18.8 kB 🔴 +18.8 kB 🔴 +4.76 kB 🔴 +4.22 kB
assets/KeybindingPanel-4by8QD5O.js (removed) 12.6 kB 🟢 -12.6 kB 🟢 -3.63 kB 🟢 -3.21 kB
assets/KeybindingPanel-Cestyf9w.js (new) 12.6 kB 🔴 +12.6 kB 🔴 +3.63 kB 🔴 +3.21 kB
assets/ExtensionPanel-BK0OFm0a.js (removed) 9.49 kB 🟢 -9.49 kB 🟢 -2.69 kB 🟢 -2.4 kB
assets/ExtensionPanel-Dkq_NXJB.js (new) 9.49 kB 🔴 +9.49 kB 🔴 +2.69 kB 🔴 +2.4 kB
assets/AboutPanel-BWW_JnV8.js (new) 8.62 kB 🔴 +8.62 kB 🔴 +2.46 kB 🔴 +2.21 kB
assets/AboutPanel-De1jGRtR.js (removed) 8.62 kB 🟢 -8.62 kB 🟢 -2.45 kB 🟢 -2.21 kB
assets/ServerConfigPanel-BlFCWREc.js (removed) 6.64 kB 🟢 -6.64 kB 🟢 -2.15 kB 🟢 -1.93 kB
assets/ServerConfigPanel-HbLQRDY7.js (new) 6.64 kB 🔴 +6.64 kB 🔴 +2.16 kB 🔴 +1.93 kB
assets/UserPanel-H9_rSh1A.js (removed) 6.28 kB 🟢 -6.28 kB 🟢 -2.02 kB 🟢 -1.77 kB
assets/UserPanel-k3TURjei.js (new) 6.28 kB 🔴 +6.28 kB 🔴 +2.02 kB 🔴 +1.77 kB
assets/cloudRemoteConfig-DujwtKMe.js (removed) 1.44 kB 🟢 -1.44 kB 🟢 -698 B 🟢 -601 B
assets/cloudRemoteConfig-WXYAP71Z.js (new) 1.44 kB 🔴 +1.44 kB 🔴 +700 B 🔴 +602 B
assets/refreshRemoteConfig-C9pns1R0.js (removed) 1.13 kB 🟢 -1.13 kB 🟢 -511 B 🟢 -447 B
assets/refreshRemoteConfig-D3RHNbrZ.js (new) 1.13 kB 🔴 +1.13 kB 🔴 +514 B 🔴 +450 B
assets/refreshRemoteConfig-B99G1Lxe.js (new) 345 B 🔴 +345 B 🔴 +205 B 🔴 +205 B
assets/refreshRemoteConfig-BTsOrgXm.js (removed) 345 B 🟢 -345 B 🟢 -205 B 🟢 -180 B
assets/config-HAvaVehF.js 1.01 kB 1.01 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/remoteConfig-CUBB_j_I.js 581 B 581 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BgcR6REE.js 25 kB 25 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BmEXiKRV.js 32 kB 32 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BNs5rnMt.js 24.1 kB 24.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C5jqELHS.js 23.6 kB 23.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CKCscONF.js 28.1 kB 28.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CzcL_U24.js 20.8 kB 20.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-D95NIw0v.js 26.8 kB 26.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DmYc-PH9.js 24.2 kB 24.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DQe4OZm2.js 25.7 kB 25.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Dxocpd_-.js 20.3 kB 20.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-f2yAwEpW.js 23.3 kB 23.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 12 added / 12 removed

User & Accounts — 16 kB (baseline 16 kB) • ⚪ 0 B

Authentication, profile, and account management bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/auth-_QnsX2r6.js (new) 3.4 kB 🔴 +3.4 kB 🔴 +1.18 kB 🔴 +994 B
assets/auth-CrOcbCdP.js (removed) 3.4 kB 🟢 -3.4 kB 🟢 -1.18 kB 🟢 -996 B
assets/SignUpForm-ChgceXFD.js (removed) 3.01 kB 🟢 -3.01 kB 🟢 -1.23 kB 🟢 -1.11 kB
assets/SignUpForm-gfOgXejF.js (new) 3.01 kB 🔴 +3.01 kB 🔴 +1.24 kB 🔴 +1.09 kB
assets/UpdatePasswordContent-CpDsTDC9.js (removed) 2.37 kB 🟢 -2.37 kB 🟢 -1.07 kB 🟢 -948 B
assets/UpdatePasswordContent-tvV2s5zT.js (new) 2.37 kB 🔴 +2.37 kB 🔴 +1.07 kB 🔴 +949 B
assets/firebaseAuthStore-CPDEy8Rs.js (new) 790 B 🔴 +790 B 🔴 +390 B 🔴 +350 B
assets/firebaseAuthStore-CZedc9jy.js (removed) 790 B 🟢 -790 B 🟢 -387 B 🟢 -350 B
assets/auth-DW9xXuqF.js (new) 347 B 🔴 +347 B 🔴 +221 B 🔴 +185 B
assets/auth-UQ26rpOb.js (removed) 347 B 🟢 -347 B 🟢 -220 B 🟢 -187 B
assets/PasswordFields-BAi3GPM-.js 4.51 kB 4.51 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WorkspaceProfilePic-B0BztYjc.js 1.57 kB 1.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 5 added / 5 removed

Editors & Dialogs — 3.47 kB (baseline 3.47 kB) • ⚪ 0 B

Modals, dialogs, drawers, and in-app editors

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useSubscriptionDialog-E0XzgXmb.js (new) 2.68 kB 🔴 +2.68 kB 🔴 +1.32 kB 🔴 +1.17 kB
assets/useSubscriptionDialog-uBpo_u0d.js (removed) 2.68 kB 🟢 -2.68 kB 🟢 -1.32 kB 🟢 -1.17 kB
assets/useSubscriptionDialog-C4lmhS8x.js (removed) 783 B 🟢 -783 B 🟢 -384 B 🟢 -346 B
assets/useSubscriptionDialog-imjFi-FF.js (new) 783 B 🔴 +783 B 🔴 +388 B 🔴 +346 B

Status: 2 added / 2 removed

UI Components — 41.5 kB (baseline 37.8 kB) • 🔴 +3.72 kB

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useTerminalTabs-BgXyJz6O.js (removed) 9.9 kB 🟢 -9.9 kB 🟢 -3.4 kB 🟢 -2.99 kB
assets/useTerminalTabs-BVwv729E.js (new) 9.9 kB 🔴 +9.9 kB 🔴 +3.41 kB 🔴 +3 kB
assets/ComfyQueueButton-BkiWgNLE.js (new) 7.13 kB 🔴 +7.13 kB 🔴 +2.31 kB 🔴 +2.06 kB
assets/ComfyQueueButton-JN1Fpe3t.js (removed) 7.13 kB 🟢 -7.13 kB 🟢 -2.31 kB 🟢 -2.06 kB
assets/FormSearchInput-CNsLdTEC.js (new) 3.72 kB 🔴 +3.72 kB 🔴 +1.54 kB 🔴 +1.35 kB
assets/SubscribeButton-BFkdpAsU.js (new) 3.68 kB 🔴 +3.68 kB 🔴 +1.38 kB 🔴 +1.24 kB
assets/SubscribeButton-DLP3-hTf.js (removed) 3.68 kB 🟢 -3.68 kB 🟢 -1.38 kB 🟢 -1.21 kB
assets/cloudFeedbackTopbarButton-CD5esHT8.js (removed) 1.6 kB 🟢 -1.6 kB 🟢 -856 B 🟢 -762 B
assets/cloudFeedbackTopbarButton-CqVVcM3V.js (new) 1.6 kB 🔴 +1.6 kB 🔴 +857 B 🔴 +762 B
assets/ComfyQueueButton-DNn95fYA.js (removed) 795 B 🟢 -795 B 🟢 -391 B 🟢 -354 B
assets/ComfyQueueButton-oIjqk3QT.js (new) 795 B 🔴 +795 B 🔴 +394 B 🔴 +358 B
assets/Button-ChqYCdrL.js 3 kB 3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CloudBadge-DtjkqbcY.js 1.2 kB 1.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/TopbarBadge-BsZTG314.js 7.52 kB 7.52 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserAvatar-Dtdiv1Hu.js 1.17 kB 1.17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-DVfWCi_V.js 1.84 kB 1.84 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 5 removed

Data & Services — 2.1 MB (baseline 2.1 MB) • 🔴 +54 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/dialogService-VV0BDeHB.js (new) 1.3 MB 🔴 +1.3 MB 🔴 +298 kB 🔴 +232 kB
assets/dialogService-BXfCe7Zs.js (removed) 1.3 MB 🟢 -1.3 MB 🟢 -298 kB 🟢 -231 kB
assets/api-CkLvPPeO.js (removed) 640 kB 🟢 -640 kB 🟢 -144 kB 🟢 -115 kB
assets/api-CQNNuHZd.js (new) 640 kB 🔴 +640 kB 🔴 +144 kB 🔴 +116 kB
assets/load3dService-D12j4dBR.js (removed) 91.1 kB 🟢 -91.1 kB 🟢 -19.1 kB 🟢 -16.4 kB
assets/load3dService-DZSKPKaJ.js (new) 91.1 kB 🔴 +91.1 kB 🔴 +19.1 kB 🔴 +16.4 kB
assets/teamWorkspaceStore-Br6ccVgi.js (new) 27.1 kB 🔴 +27.1 kB 🔴 +6.12 kB 🔴 +5.41 kB
assets/teamWorkspaceStore-C24bfLFK.js (removed) 27.1 kB 🟢 -27.1 kB 🟢 -6.12 kB 🟢 -5.41 kB
assets/systemStatsStore-D79Iptpt.js (removed) 12.3 kB 🟢 -12.3 kB 🟢 -4.29 kB 🟢 -3.77 kB
assets/systemStatsStore-DU8BbLPA.js (new) 12.3 kB 🔴 +12.3 kB 🔴 +4.29 kB 🔴 +3.77 kB
assets/releaseStore-CWyZyVIL.js (removed) 8.14 kB 🟢 -8.14 kB 🟢 -2.24 kB 🟢 -1.97 kB
assets/releaseStore-j2-nwPrz.js (new) 8.14 kB 🔴 +8.14 kB 🔴 +2.23 kB 🔴 +1.97 kB
assets/keybindingService-133wrjSP.js (new) 6.58 kB 🔴 +6.58 kB 🔴 +1.71 kB 🔴 +1.48 kB
assets/keybindingService-D6hi3LGe.js (removed) 6.58 kB 🟢 -6.58 kB 🟢 -1.71 kB 🟢 -1.48 kB
assets/bootstrapStore-Ca-vNW0D.js (removed) 2.13 kB 🟢 -2.13 kB 🟢 -882 B 🟢 -813 B
assets/bootstrapStore-Dkt-LQS1.js (new) 2.13 kB 🔴 +2.13 kB 🔴 +882 B 🔴 +811 B
assets/userStore-agIQfIqz.js (removed) 1.85 kB 🟢 -1.85 kB 🟢 -719 B 🟢 -671 B
assets/userStore-moczqKpD.js (new) 1.85 kB 🔴 +1.85 kB 🔴 +721 B 🔴 +634 B
assets/audioService-Bs0zXIlX.js (removed) 1.73 kB 🟢 -1.73 kB 🟢 -845 B 🟢 -732 B
assets/audioService-WHj0a5L_.js (new) 1.73 kB 🔴 +1.73 kB 🔴 +847 B 🔴 +726 B
assets/releaseStore-CwRuSD2T.js (new) 762 B 🔴 +762 B 🔴 +385 B 🔴 +340 B
assets/releaseStore-NPf2r1SY.js (removed) 762 B 🟢 -762 B 🟢 -383 B 🟢 -339 B
assets/dialogStore-D2gUGUn6.js 4.1 kB 4.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/serverConfigStore-DB58Z5s2.js 2.32 kB 2.32 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 11 added / 11 removed

Utilities & Hooks — 234 kB (baseline 234 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/useConflictDetection-DNGmrEok.js (new) 177 kB 🔴 +177 kB 🔴 +38.9 kB 🔴 +32.4 kB
assets/useConflictDetection-Dv4fpdfb.js (removed) 177 kB 🟢 -177 kB 🟢 -38.9 kB 🟢 -32.4 kB
assets/useLoad3d-813ZrdYk.js (new) 14.4 kB 🔴 +14.4 kB 🔴 +3.56 kB 🔴 +3.14 kB
assets/useLoad3d-HVnlTzAw.js (removed) 14.4 kB 🟢 -14.4 kB 🟢 -3.56 kB 🟢 -3.14 kB
assets/useLoad3dViewer-BNt_5zqE.js (new) 14.2 kB 🔴 +14.2 kB 🔴 +3.16 kB 🔴 +2.8 kB
assets/useLoad3dViewer-D1C_8wD2.js (removed) 14.2 kB 🟢 -14.2 kB 🟢 -3.16 kB 🟢 -2.8 kB
assets/useErrorHandling-Bc5VkDeQ.js (removed) 4.26 kB 🟢 -4.26 kB 🟢 -1.34 kB 🟢 -1.18 kB
assets/useErrorHandling-CG95TGa-.js (new) 4.26 kB 🔴 +4.26 kB 🔴 +1.34 kB 🔴 +1.18 kB
assets/useWorkspaceUI-BVThnTwa.js (removed) 3.16 kB 🟢 -3.16 kB 🟢 -883 B 🟢 -765 B
assets/useWorkspaceUI-lvEXNp2S.js (new) 3.16 kB 🔴 +3.16 kB 🔴 +882 B 🔴 +766 B
assets/useSubscriptionActions-2ac_YFU2.js (removed) 1.76 kB 🟢 -1.76 kB 🟢 -755 B 🟢 -652 B
assets/useSubscriptionActions-CDmDWziW.js (new) 1.76 kB 🔴 +1.76 kB 🔴 +754 B 🔴 +652 B
assets/subscriptionCheckoutUtil-BT4lo_vU.js (removed) 1.75 kB 🟢 -1.75 kB 🟢 -784 B 🟢 -688 B
assets/subscriptionCheckoutUtil-CmJda0PA.js (new) 1.75 kB 🔴 +1.75 kB 🔴 +784 B 🔴 +689 B
assets/useSubscriptionCredits-Bd96By84.js (removed) 1.07 kB 🟢 -1.07 kB 🟢 -502 B 🟢 -441 B
assets/useSubscriptionCredits-CzSUhAd0.js (new) 1.07 kB 🔴 +1.07 kB 🔴 +500 B 🔴 +439 B
assets/useLoad3d-CDNeCuSq.js (removed) 861 B 🟢 -861 B 🟢 -427 B 🟢 -383 B
assets/useLoad3d-Dy2Vxa5h.js (new) 861 B 🔴 +861 B 🔴 +427 B 🔴 +382 B
assets/audioUtils-BV1nsAIi.js (new) 858 B 🔴 +858 B 🔴 +499 B 🔴 +418 B
assets/audioUtils-DYhoekip.js (removed) 858 B 🟢 -858 B 🟢 -498 B 🟢 -418 B
assets/useLoad3dViewer-B2xUftMd.js (new) 840 B 🔴 +840 B 🔴 +411 B 🔴 +375 B
assets/useLoad3dViewer-DGUQm5Ea.js (removed) 840 B 🟢 -840 B 🟢 -411 B 🟢 -371 B
assets/useCurrentUser-BjM1KBLT.js (removed) 724 B 🟢 -724 B 🟢 -372 B 🟢 -330 B
assets/useCurrentUser-C4dtX4yy.js (new) 724 B 🔴 +724 B 🔴 +376 B 🔴 +332 B
assets/_plugin-vue_export-helper-CAbbkOlw.js 315 B 315 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/colorUtil-FW_Ghng2.js 7 kB 7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/envUtil-Djb4sHrV.js 524 B 524 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/markdownRendererUtil-Cc2LFa5s.js 1.56 kB 1.56 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/networkUtil-Du2a_n7V.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SkeletonUtils-DwBAnKr-.js 133 B 133 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useCopyToClipboard-ihQ2636T.js 1.57 kB 1.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/useExternalLink-Br3OkPS9.js 1.63 kB 1.63 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 12 added / 12 removed

Vendor & Third-Party — 9.37 MB (baseline 9.37 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-axios-D0w6WYH0.js 71.6 kB 71.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-chart-CIdI9Yl4.js 399 kB 399 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-firebase-CLEC0CcJ.js 842 kB 842 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-i18n-C6_f776o.js 132 kB 132 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-markdown-BkVHYrKV.js 102 kB 102 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-DPcKX1Hx.js 2.16 MB 2.16 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-Dw8RivU1.js 1.74 MB 1.74 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-reka-ui-CPrt7lw0.js 240 kB 240 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-sentry-BVA5kbUC.js 183 kB 183 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-CJhOuqDg.js 1.8 MB 1.8 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-CvX7mojg.js 632 kB 632 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-core-BBP9kkTE.js 312 kB 312 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vueuse-CS5mlw4Q.js 111 kB 111 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-DOEEpxXk.js 398 kB 398 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-yjs-BtrvIr1x.js 143 kB 143 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-zod-gAWmQIF-.js 110 kB 110 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 7.07 MB (baseline 7.08 MB) • 🟢 -11.7 kB

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/core-BkHm7yo7.js (removed) 71.4 kB 🟢 -71.4 kB 🟢 -18.4 kB 🟢 -15.8 kB
assets/core-FhP6QWac.js (new) 71.4 kB 🔴 +71.4 kB 🔴 +18.4 kB 🔴 +15.8 kB
assets/groupNode-rn1Qqa4-.js (new) 70.9 kB 🔴 +70.9 kB 🔴 +17.5 kB 🔴 +15.4 kB
assets/groupNode-wApeescD.js (removed) 70.9 kB 🟢 -70.9 kB 🟢 -17.5 kB 🟢 -15.4 kB
assets/WidgetSelect-CFqcAiR7.js (new) 57.2 kB 🔴 +57.2 kB 🔴 +12.2 kB 🔴 +10.5 kB
assets/WidgetSelect-C2mhL8wM.js (removed) 56.6 kB 🟢 -56.6 kB 🟢 -12 kB 🟢 -10.4 kB
assets/SettingDialogContent-2-j2O9HA.js (removed) 30.8 kB 🟢 -30.8 kB 🟢 -8 kB 🟢 -7.06 kB
assets/SettingDialogContent-Qt0m7czA.js (new) 30.8 kB 🔴 +30.8 kB 🔴 +8.01 kB 🔴 +7.05 kB
assets/Load3DControls-ClczJxg_.js (removed) 30.8 kB 🟢 -30.8 kB 🟢 -5.33 kB 🟢 -4.64 kB
assets/Load3DControls-kw1cz_rB.js (new) 30.8 kB 🔴 +30.8 kB 🔴 +5.33 kB 🔴 +4.64 kB
assets/SubscriptionRequiredDialogContent-CGHR74V3.js (removed) 25.4 kB 🟢 -25.4 kB 🟢 -6.36 kB 🟢 -5.58 kB
assets/SubscriptionRequiredDialogContent-Cgti7CO2.js (new) 25.4 kB 🔴 +25.4 kB 🔴 +6.36 kB 🔴 +5.59 kB
assets/Load3dViewerContent-C1v0y_iv.js (removed) 23.2 kB 🟢 -23.2 kB 🟢 -5.24 kB 🟢 -4.54 kB
assets/Load3dViewerContent-C3RPPXWI.js (new) 23.2 kB 🔴 +23.2 kB 🔴 +5.24 kB 🔴 +4.54 kB
assets/WidgetImageCrop-BXz9dYki.js (removed) 22.3 kB 🟢 -22.3 kB 🟢 -5.51 kB 🟢 -4.84 kB
assets/WidgetImageCrop-CvUsPSDB.js (new) 22.3 kB 🔴 +22.3 kB 🔴 +5.51 kB 🔴 +4.85 kB
assets/FormItem-BZ2LJKNc.js (removed) 20.2 kB 🟢 -20.2 kB 🟢 -4.87 kB 🟢 -4.25 kB
assets/FormItem-D3s-Dxh0.js (new) 20.2 kB 🔴 +20.2 kB 🔴 +4.87 kB 🔴 +4.25 kB
assets/CurrentUserPopoverWorkspace-aJYAtyKm.js (removed) 19.7 kB 🟢 -19.7 kB 🟢 -4.74 kB 🟢 -4.23 kB
assets/CurrentUserPopoverWorkspace-BFZSkSyR.js (new) 19.7 kB 🔴 +19.7 kB 🔴 +4.74 kB 🔴 +4.22 kB
assets/SignInContent-7uf5xfDV.js (removed) 19 kB 🟢 -19 kB 🟢 -4.8 kB 🟢 -4.2 kB
assets/SignInContent-CGMbtaS1.js (new) 19 kB 🔴 +19 kB 🔴 +4.8 kB 🔴 +4.2 kB
assets/WidgetRecordAudio-CXdKngFb.js (removed) 17.2 kB 🟢 -17.2 kB 🟢 -4.92 kB 🟢 -4.4 kB
assets/WidgetRecordAudio-DHPHxE9B.js (new) 17.2 kB 🔴 +17.2 kB 🔴 +4.93 kB 🔴 +4.4 kB
assets/TopUpCreditsDialogContent-DPs4ICWL.js (new) 16.9 kB 🔴 +16.9 kB 🔴 +4.8 kB 🔴 +4.25 kB
assets/TopUpCreditsDialogContent-DrBuJ0vs.js (removed) 16.9 kB 🟢 -16.9 kB 🟢 -4.79 kB 🟢 -4.24 kB
assets/Load3D-CH80QqUf.js (new) 16.2 kB 🔴 +16.2 kB 🔴 +4.04 kB 🔴 +3.51 kB
assets/Load3D-DW8PJ7GG.js (removed) 16.2 kB 🟢 -16.2 kB 🟢 -4.03 kB 🟢 -3.5 kB
assets/MissingModelsWarning-D0nO-zCE.js (new) 16.1 kB 🔴 +16.1 kB 🔴 +4.4 kB 🔴 +3.9 kB
assets/MissingModelsWarning-Dl0V0KoO.js (removed) 16.1 kB 🟢 -16.1 kB 🟢 -4.4 kB 🟢 -3.9 kB
assets/SubscriptionPanelContentWorkspace-D3kDPzWL.js (removed) 15.8 kB 🟢 -15.8 kB 🟢 -4.03 kB 🟢 -3.54 kB
assets/SubscriptionPanelContentWorkspace-Dxqmc8Tp.js (new) 15.8 kB 🔴 +15.8 kB 🔴 +4.03 kB 🔴 +3.54 kB
assets/WidgetInputNumber-BMcpRtzZ.js (removed) 15.4 kB 🟢 -15.4 kB 🟢 -4.2 kB 🟢 -3.74 kB
assets/WidgetInputNumber-hMMlu5kT.js (new) 15.4 kB 🔴 +15.4 kB 🔴 +4.2 kB 🔴 +3.74 kB
assets/load3d-BrM2Fv31.js (removed) 14.8 kB 🟢 -14.8 kB 🟢 -4.18 kB 🟢 -3.64 kB
assets/load3d-CHmdecKu.js (new) 14.8 kB 🔴 +14.8 kB 🔴 +4.18 kB 🔴 +3.64 kB
assets/LazyImage-CVvKb-rW.js (removed) 12.3 kB 🟢 -12.3 kB 🟢 -3.78 kB 🟢 -3.32 kB
assets/NodeConflictDialogContent-Dm8l5R8l.js (new) 10.5 kB 🔴 +10.5 kB 🔴 +2.37 kB 🔴 +2.08 kB
assets/NodeConflictDialogContent-nBS_sRgu.js (removed) 10.5 kB 🟢 -10.5 kB 🟢 -2.36 kB 🟢 -2.08 kB
assets/AudioPreviewPlayer-CnWAR0dI.js (removed) 10.1 kB 🟢 -10.1 kB 🟢 -2.98 kB 🟢 -2.67 kB
assets/AudioPreviewPlayer-o425lxJ0.js (new) 10.1 kB 🔴 +10.1 kB 🔴 +2.99 kB 🔴 +2.69 kB
assets/nodeTemplates-FWNpYtSL.js (removed) 9.33 kB 🟢 -9.33 kB 🟢 -3.27 kB 🟢 -2.87 kB
assets/nodeTemplates-LWjyILC5.js (new) 9.33 kB 🔴 +9.33 kB 🔴 +3.27 kB 🔴 +2.89 kB
assets/InviteMemberDialogContent-C6Feqc-K.js (removed) 7.95 kB 🟢 -7.95 kB 🟢 -2.56 kB 🟢 -2.22 kB
assets/InviteMemberDialogContent-isJ2JuIh.js (new) 7.95 kB 🔴 +7.95 kB 🔴 +2.57 kB 🔴 +2.22 kB
assets/WidgetWithControl-BfOnsjPQ.js (new) 6.97 kB 🔴 +6.97 kB 🔴 +2.59 kB 🔴 +2.31 kB
assets/WidgetWithControl-CS5FiXYr.js (removed) 6.97 kB 🟢 -6.97 kB 🟢 -2.59 kB 🟢 -2.31 kB
assets/Load3DConfiguration-0nE3Sm0m.js (removed) 6.36 kB 🟢 -6.36 kB 🟢 -1.92 kB 🟢 -1.69 kB
assets/Load3DConfiguration-hHVWAokm.js (new) 6.36 kB 🔴 +6.36 kB 🔴 +1.93 kB 🔴 +1.69 kB
assets/MissingNodesContent-CO54z5CT.js (removed) 6.14 kB 🟢 -6.14 kB 🟢 -2.08 kB 🟢 -1.85 kB
assets/MissingNodesContent-yn4Bnh3o.js (new) 6.14 kB 🔴 +6.14 kB 🔴 +2.08 kB 🔴 +1.85 kB
assets/CreateWorkspaceDialogContent-aE6fFW-d.js (removed) 5.58 kB 🟢 -5.58 kB 🟢 -2 kB 🟢 -1.75 kB
assets/CreateWorkspaceDialogContent-Ce7kga89.js (new) 5.58 kB 🔴 +5.58 kB 🔴 +2 kB 🔴 +1.74 kB
assets/EditWorkspaceDialogContent-CjYGf0Iz.js (new) 5.38 kB 🔴 +5.38 kB 🔴 +1.96 kB 🔴 +1.7 kB
assets/EditWorkspaceDialogContent-DyQSw_lc.js (removed) 5.38 kB 🟢 -5.38 kB 🟢 -1.96 kB 🟢 -1.7 kB
assets/ValueControlPopover-4TlNYSsp.js (new) 4.92 kB 🔴 +4.92 kB 🔴 +1.77 kB 🔴 +1.58 kB
assets/ValueControlPopover-CUleXdH0.js (removed) 4.92 kB 🟢 -4.92 kB 🟢 -1.77 kB 🟢 -1.58 kB
assets/Preview3d-5JcTsTs7.js (new) 4.82 kB 🔴 +4.82 kB 🔴 +1.57 kB 🔴 +1.37 kB
assets/Preview3d-Dcs8Huk6.js (removed) 4.82 kB 🟢 -4.82 kB 🟢 -1.57 kB 🟢 -1.36 kB
assets/MissingNodesFooter-ChZCnsnB.js (new) 4.8 kB 🔴 +4.8 kB 🔴 +1.78 kB 🔴 +1.58 kB
assets/MissingNodesFooter-m13DAoNg.js (removed) 4.8 kB 🟢 -4.8 kB 🟢 -1.78 kB 🟢 -1.57 kB
assets/DeleteWorkspaceDialogContent-DhMQQ8x2.js (removed) 4.28 kB 🟢 -4.28 kB 🟢 -1.64 kB 🟢 -1.43 kB
assets/DeleteWorkspaceDialogContent-WXw586hv.js (new) 4.28 kB 🔴 +4.28 kB 🔴 +1.65 kB 🔴 +1.43 kB
assets/LeaveWorkspaceDialogContent-CBp0RAXd.js (removed) 4.11 kB 🟢 -4.11 kB 🟢 -1.59 kB 🟢 -1.38 kB
assets/LeaveWorkspaceDialogContent-vjM2H5qH.js (new) 4.11 kB 🔴 +4.11 kB 🔴 +1.59 kB 🔴 +1.38 kB
assets/RemoveMemberDialogContent-BO5lzO25.js (removed) 4.09 kB 🟢 -4.09 kB 🟢 -1.54 kB 🟢 -1.34 kB
assets/RemoveMemberDialogContent-DHDUanHB.js (new) 4.09 kB 🔴 +4.09 kB 🔴 +1.54 kB 🔴 +1.34 kB
assets/RevokeInviteDialogContent-CeSsDmeX.js (new) 4 kB 🔴 +4 kB 🔴 +1.55 kB 🔴 +1.36 kB
assets/RevokeInviteDialogContent-CyEW43oz.js (removed) 4 kB 🟢 -4 kB 🟢 -1.55 kB 🟢 -1.36 kB
assets/saveMesh-DcTrVfzE.js (removed) 3.38 kB 🟢 -3.38 kB 🟢 -1.45 kB 🟢 -1.29 kB
assets/saveMesh-DNyDElXG.js (new) 3.38 kB 🔴 +3.38 kB 🔴 +1.45 kB 🔴 +1.3 kB
assets/cloudSessionCookie-7TGmwvlj.js (removed) 3.07 kB 🟢 -3.07 kB 🟢 -1.08 kB 🟢 -974 B
assets/cloudSessionCookie-D-cAP8Pi.js (new) 3.07 kB 🔴 +3.07 kB 🔴 +1.08 kB 🔴 +973 B
assets/GlobalToast-1DfJ45Id.js (removed) 2.34 kB 🟢 -2.34 kB 🟢 -965 B 🟢 -806 B
assets/GlobalToast-jXPQGaVq.js (new) 2.34 kB 🔴 +2.34 kB 🔴 +965 B 🔴 +808 B
assets/SubscribeToRun-Aj_gqysj.js (removed) 2.16 kB 🟢 -2.16 kB 🟢 -990 B 🟢 -868 B
assets/SubscribeToRun-D0h_5Rc-.js (new) 2.16 kB 🔴 +2.16 kB 🔴 +989 B 🔴 +871 B
assets/CloudRunButtonWrapper-B3MOtGaA.js (removed) 1.67 kB 🟢 -1.67 kB 🟢 -780 B 🟢 -700 B
assets/CloudRunButtonWrapper-DL4k_erz.js (new) 1.67 kB 🔴 +1.67 kB 🔴 +781 B 🔴 +693 B
assets/cloudBadges-C-3XyGwm.js (removed) 1.37 kB 🟢 -1.37 kB 🟢 -699 B 🟢 -615 B
assets/cloudBadges-DeZbTK5K.js (new) 1.37 kB 🔴 +1.37 kB 🔴 +702 B 🔴 +615 B
assets/cloudSubscription-B77JoDAn.js (removed) 1.32 kB 🟢 -1.32 kB 🟢 -651 B 🟢 -567 B
assets/cloudSubscription-CfqhwgT6.js (new) 1.32 kB 🔴 +1.32 kB 🔴 +653 B 🔴 +565 B
assets/SubscriptionPanelContentWorkspace-C-ZcN8cG.js (removed) 1.07 kB 🟢 -1.07 kB 🟢 -480 B 🟢 -421 B
assets/SubscriptionPanelContentWorkspace-C9h29cEa.js (new) 1.07 kB 🔴 +1.07 kB 🔴 +480 B 🔴 +421 B
assets/Load3D-CzTCAxmB.js (new) 1.04 kB 🔴 +1.04 kB 🔴 +488 B 🔴 +436 B
assets/Load3D-Damv7MwL.js (removed) 1.04 kB 🟢 -1.04 kB 🟢 -487 B 🟢 -433 B
assets/nightlyBadges-M5sg9x4P.js (removed) 1 kB 🟢 -1 kB 🟢 -535 B 🟢 -473 B
assets/nightlyBadges-MEF1vymC.js (new) 1 kB 🔴 +1 kB 🔴 +537 B 🔴 +477 B
assets/Load3dViewerContent-D1JKwmWU.js (new) 961 B 🔴 +961 B 🔴 +457 B 🔴 +405 B
assets/Load3dViewerContent-DKtF7k9V.js (removed) 961 B 🟢 -961 B 🟢 -456 B 🟢 -407 B
assets/SettingDialogContent-DJ2LKWdn.js (new) 917 B 🔴 +917 B 🔴 +441 B 🔴 +389 B
assets/SettingDialogContent-Kv3eqSvV.js (removed) 917 B 🟢 -917 B 🟢 -443 B 🟢 -393 B
assets/graphHasMissingNodes-C-5HXePo.js (new) 761 B 🔴 +761 B 🔴 +373 B 🔴 +327 B
assets/graphHasMissingNodes-D9HwVMq2.js (removed) 761 B 🟢 -761 B 🟢 -373 B 🟢 -326 B
assets/WidgetLegacy-BTvzohM3.js (new) 747 B 🔴 +747 B 🔴 +387 B 🔴 +340 B
assets/WidgetLegacy-DWcILVxw.js (removed) 747 B 🟢 -747 B 🟢 -385 B 🟢 -337 B
assets/WidgetInputNumber-C9w9Ogpj.js (removed) 392 B 🟢 -392 B 🟢 -231 B 🟢 -197 B
assets/WidgetInputNumber-DzdI7Jir.js (new) 392 B 🔴 +392 B 🔴 +230 B 🔴 +195 B
assets/AnimationControls-bPyINTJI.js 4.61 kB 4.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ApiNodesSignInContent-BIJKq20L.js 2.69 kB 2.69 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/auto-DjoqfnTX.js 1.7 kB 1.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/BaseViewTemplate-BnXUotno.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/comfy-logo-single-DCVL1uOL.js 198 B 198 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ComfyOrgHeader-32ZIoIYN.js 909 B 909 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-7WXVxhf9.js 14.6 kB 14.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BNcWkRcH.js 15.2 kB 15.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Cchriln7.js 18 kB 18 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-COsT3jlc.js 16 kB 16 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CpqJ59mV.js 16.8 kB 16.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-dco-b4jy.js 16.7 kB 16.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-Dj4qNjPR.js 15.4 kB 15.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-gwZZf095.js 14.4 kB 14.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-jn33Krva.js 15.4 kB 15.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-kIN_T4OP.js 16.3 kB 16.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-mTEY_dzO.js 15.4 kB 15.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-CU6mOd8i.js 478 kB 478 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/i18n-wGA3C3Hi.js 199 B 199 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeContent-VPjQzi79.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeFooter-B2l9_-Av.js 1.88 kB 1.88 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ImportFailedNodeHeader-DUns4_x2.js 1.08 kB 1.08 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-9VWyHo5z.js 136 kB 136 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B8iCY4y4.js 155 kB 155 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BFqZCm1H.js 131 kB 131 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CgmTJMw2.js 113 kB 113 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-D2_fl4nn.js 148 kB 148 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DbGv8BCU.js 114 kB 114 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DigTCF_h.js 129 kB 129 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DuAAxgfq.js 179 kB 179 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DYZBa_3M.js 161 kB 161 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-wdnI-QZq.js 128 kB 128 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Zns-zxeS.js 133 kB 133 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Media3DTop-DTYkrVtB.js 1.82 kB 1.82 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-AFmsiWi3.js 1.43 kB 1.43 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-ATOoJCQr.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-CQw3f2T6.js 2.23 kB 2.23 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MissingNodesHeader-BOlbqJ0O.js 1.09 kB 1.09 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/mixpanel.module-Dq6XmUX_.js 92 B 92 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/NodeConflictFooter-C8QCTAMD.js 2.37 kB 2.37 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/NodeConflictHeader-DRxQs5TH.js 1.09 kB 1.09 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-aApbAbNI.js 360 kB 360 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-B2JRfCRl.js 332 kB 332 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BbVIS5BG.js 357 kB 357 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BddTsShn.js 374 kB 374 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CEMSHoZg.js 360 kB 360 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Cfjv7JEn.js 364 kB 364 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-COMqCnF4.js 353 kB 353 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-oMRTTpzO.js 405 kB 405 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-PGdfR_x_.js 441 kB 441 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-SDKvs0-9.js 404 kB 404 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-wKqgWC3H.js 329 kB 329 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/PanelTemplate-C1h0RxBM.js 1.2 kB 1.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/previousFullPath-DsBk66MD.js 665 B 665 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/rolldown-runtime-Ca2S-reV.js 1.87 kB 1.87 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SelectValue-RIZ7-gt8.js 8.81 kB 8.81 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SettingDialogHeader-BHt-6Ao_.js 1.62 kB 1.62 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/SettingDialogHeader-D5wathvf.js 244 B 244 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/signInSchema-5NW8sj_6.js 1.53 kB 1.53 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Slider-Bh_ZdHn9.js 3.52 kB 3.52 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/src-DAMctjF_.js 251 B 251 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/types-VDank0gz.js 318 B 318 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widget-RLUqfB5N.js 445 B 445 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-2w5BjjHm.js 3.94 kB 3.94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetBoundingBox-Djm16aYN.js 131 B 131 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-Dsp6bf_j.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetColorPicker-jDbRm4n6.js 2.9 kB 2.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetGalleria-C8ikSQqn.js 3.61 kB 3.61 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-B1RSu0_k.js 3.1 kB 3.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputText-MXN3EUoN.js 1.85 kB 1.85 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField-BcUSnWUK.js 1.95 kB 1.95 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetMarkdown-wePHc2fh.js 2.88 kB 2.88 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-DyQHILEf.js 1.1 kB 1.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetTextarea-COgaptkR.js 3.09 kB 3.09 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-CoKD027B.js 2.5 kB 2.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetTypes-BCsKJASV.js 393 B 393 B ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 49 added / 50 removed

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In
`@src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue`:
- Around line 79-91: The gridTemplateColumns property in the computed gridStyle
is redundant because VirtualGrid's mergedGridStyle will override it with
repeat(${maxColumns}, minmax(0, 1fr)) when maxColumns is finite (which it always
is here), so remove the gridTemplateColumns key from the gridStyle computed
object (leave display, gap, padding, width intact) to avoid dead code; reference
the gridStyle computed, layoutMode.value conditions, and the
VirtualGrid/mergedGridStyle behavior when making the change.
- Line 30: Replace the non-destructured props assignment const props =
defineProps<Props>() with reactive destructuring so the component accesses props
directly (e.g., const { items, ... } = defineProps<Props>()), then update usages
(notably where items is referenced around the template and the code at the
former line 95) to use items directly; ensure you keep the Props type on
defineProps and preserve reactivity by using the direct destructuring pattern
recommended by the guidelines.

- Consolidate layout config into single computed with Record type
- Use reactive props destructuring per AGENTS.md
- Change h-[640px] back to max-h-[640px] for proper sizing
- Replace hardcoded zinc color with semantic text-muted-foreground
- Add defineSlots to VirtualGrid for type safety
- Add unit tests for VirtualGrid and FormDropdownMenu

Amp-Thread-ID: https://ampcode.com/threads/T-019c0ca8-be8d-770e-ab31-349937cd2acf
Co-authored-by: Amp <amp@ampcode.com>
@coderabbitai coderabbitai bot requested a review from DrJKL January 30, 2026 08:18
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/components/common/VirtualGrid.test.ts`:
- Around line 74-79: The test currently skips all assertions when
receivedIndices is empty which masks failures; update the assertion around the
receivedIndices checks in VirtualGrid.test (the block using receivedIndices and
the for loop) to explicitly assert that receivedIndices.length > 0 (e.g.,
expect(receivedIndices.length).toBeGreaterThan(0)) before asserting the first
index and the incremental sequence, and keep the existing loop that verifies
receivedIndices[i] === receivedIndices[i-1] + 1 so the test fails if no items
render or indices are non-sequential.
- Around line 84-101: The test "respects maxColumns prop" in VirtualGrid.test.ts
currently only checks for a grid element but doesn't assert that maxColumns: 2
influences layout; update the test that mounts VirtualGrid<TestItem> to read the
rendered element's computed style (or the element.style.gridTemplateColumns) and
assert it contains exactly two column tracks (e.g., two "px" or "fr" entries or
matches a regex for two columns), referencing the mounted wrapper and the grid
element found via wrapper.find(...) and using
getComputedStyle(gridElement.element).gridTemplateColumns (or
gridElement.element.style.gridTemplateColumns) to verify the maxColumns behavior
before calling wrapper.unmount().

In `@src/components/common/VirtualGrid.vue`:
- Around line 60-62: Remove the explicit defineSlots call (defineSlots<{ item:
(props: { item: T & { key: string }; index: number }) => unknown }>() ) from
VirtualGrid.vue; instead rely on the template-declared slot (the "item" slot
already defined at line 14) for slot typing per the coding guideline, so delete
the defineSlots invocation and ensure any TypeScript generics or props
referenced in the template stay intact to preserve type inference for the item
slot.

@christian-byrne
Copy link
Contributor Author

christian-byrne commented Jan 30, 2026

There's some issues right now like the grid not being properly truncated.

To confirm: bottleneck is the DOM insertion

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue (1)

83-84: ⚠️ Potential issue | 🟠 Major

Container needs fixed height for proper virtualization.

The PR objectives mention changing from max-h-[640px] to h-[640px], but the current code still uses max-h-[640px]. This likely explains the truncation issue you reported—VirtualGrid needs a deterministic container height to calculate the visible range correctly. With max-h, the container can shrink based on content, causing virtualization miscalculations.

🐛 Proposed fix
   <div
-    class="flex max-h-[640px] w-103 flex-col rounded-lg bg-component-node-background pt-4 outline outline-offset-[-1px] outline-node-component-border"
+    class="flex h-[640px] w-103 flex-col rounded-lg bg-component-node-background pt-4 outline outline-offset-[-1px] outline-node-component-border"
   >

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/components/common/VirtualGrid.test.ts`:
- Around line 23-46: The test can pass with zero rendered items and mask
regressions; after mounting VirtualGrid (in VirtualGrid.test.ts) and computing
renderedItems via wrapper.findAll('.test-item'), add an assertion that at least
one item is rendered (e.g., expect(renderedItems.length).toBeGreaterThan(0))
before the existing virtualization assertion that renderedItems.length is less
than items.length; update references around createItems, wrapper and
renderedItems so the test fails if nothing is rendered.

In `@src/components/common/VirtualGrid.vue`:
- Around line 9-15: The slot binding in VirtualGrid.vue uses an explicit prop
binding for item; update the <slot name="item" ...> usage to use the same-name
shorthand for the item prop (replace :item="item" with :item) while leaving the
other prop (:index="state.start + i") unchanged so it follows the repo's
slot-binding convention and matches existing styling in the component rendering
loop.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/components/common/VirtualGrid.test.ts`:
- Around line 134-151: The test "renders empty when no items provided" mounts a
wrapper but never unmounts it, which can leak DOM state; add a call to
wrapper.unmount() at the end of this test (after the expect) to tear down the
mounted component instance, or alternatively introduce a scoped variable and an
afterEach(() => wrapper?.unmount()) cleanup; reference the wrapper variable and
the test name "renders empty when no items provided" to locate where to add
wrapper.unmount().

Comment on lines 112 to 135
@@ -97,7 +131,7 @@ const searchQuery = defineModel<string>('searchQuery')
:layout="layoutMode"
@click="emit('item-click', item, index)"
/>
</div>
</div>
</template>
</VirtualGrid>
Copy link
Collaborator

@LittleSound LittleSound Feb 3, 2026

Choose a reason for hiding this comment

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

The tooltip for the file name was not displaying properly when scrolling to the bottom, and I've fixed it.

  • Fixes a VirtualGrid edge-case where grid gap wasn’t included in the measured row/column step,
    causing scrollTop to jitter near the bottom (e.g. 429.5 ↔ 429) and breaking PrimeVue tooltips
    (they auto-hide on scroll).
  • Now measures the actual grid step via offsetTop/offsetLeft and computes spacer heights by whole
    rows for stable layout.
  • Adds a unit test to lock in “row step includes gap” behavior and prevent regressions.

@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Feb 3, 2026
LittleSound
LittleSound previously approved these changes Feb 3, 2026
# Conflicts:
#	src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenu.vue
#	src/renderer/extensions/vueNodes/widgets/components/form/dropdown/FormDropdownMenuItem.vue
@LittleSound LittleSound removed their assignment Feb 3, 2026
LittleSound
LittleSound previously approved these changes Feb 3, 2026
LittleSound
LittleSound previously approved these changes Feb 3, 2026
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Feb 4, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/common/VirtualGrid.vue (1)

104-113: ⚠️ Potential issue | 🟠 Major

Spacer height undercounts partial rows, which can truncate scroll range.

rowsToHeight(itemsCount) divides by cols, so any remaining items that don’t fill a full row only contribute a fractional height. In a CSS grid, a partially filled row still consumes a full row height, so the bottom spacer becomes too short and items near the end can become unreachable. This matches the “truncation” symptoms noted in the PR discussion.

🛠️ Suggested fix
-function rowsToHeight(rows: number): string {
-  return `${(rows / cols.value) * itemHeight.value}px`
-}
+function rowsToHeight(itemsCount: number): string {
+  const rows = Math.ceil(itemsCount / cols.value)
+  return `${rows * itemHeight.value}px`
+}
🧹 Nitpick comments (1)
src/components/common/VirtualGrid.test.ts (1)

9-23: Avoid module-level mutable refs in the vueuse mock.

mockedWidth/Height/ScrollY are mutated across tests at module scope, which can leak state between cases. Use vi.hoisted() to define them for the mock and reset in beforeEach to keep tests isolated.

♻️ Suggested pattern
-import { describe, expect, it, vi } from 'vitest'
+import { beforeEach, describe, expect, it, vi } from 'vitest'
 import { nextTick, ref } from 'vue'
 
-const mockedWidth = ref(400)
-const mockedHeight = ref(200)
-const mockedScrollY = ref(0)
+const { mockedWidth, mockedHeight, mockedScrollY } = vi.hoisted(() => ({
+  mockedWidth: ref(400),
+  mockedHeight: ref(200),
+  mockedScrollY: ref(0)
+}))
+
+beforeEach(() => {
+  mockedWidth.value = 400
+  mockedHeight.value = 200
+  mockedScrollY.value = 0
+})

Based on learnings: "Keep module mocks contained; do not use global mutable state within test files; use vi.hoisted() if necessary for per-test Arrange phase manipulation".

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

Labels

area:widgets perf:speed size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants