-
Notifications
You must be signed in to change notification settings - Fork 677
feat(api-reference): virtualized operations #7210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Observer Cleanup Issue
The IntersectionObserver created in useVirtual isn't cleaned up when the component unmounts. The current watch only handles changes to the observed element, not component destruction. This leaves active observers holding references to DOM elements and callbacks, which can cause memory leaks.
packages/api-reference/src/hooks/use-virtual.ts#L7-L29
scalar/packages/api-reference/src/hooks/use-virtual.ts
Lines 7 to 29 in 012c286
| watch(el, () => { | |
| if (el.value) { | |
| observer.value?.disconnect() | |
| observer.value = new IntersectionObserver( | |
| ([entry]) => { | |
| if (entry?.isIntersecting) { | |
| isVisible.value = true | |
| nextTick(() => { | |
| placeholderHeight.value = el.value?.offsetHeight || 1000 | |
| }) | |
| } | |
| }, | |
| { | |
| rootMargin: '9000px', | |
| }, | |
| ) | |
| observer.value.observe(el.value) | |
| } else { | |
| observer.value?.disconnect() | |
| } | |
| }) |
Bug: Virtual Elements Fail to Unrender
The useVirtual hook's IntersectionObserver sets isVisible to true when an element enters the viewport but lacks logic to set it back to false when the element leaves. This causes elements to remain rendered permanently once visible, defeating the purpose of virtualization and negating its intended performance benefits.
packages/api-reference/src/hooks/use-virtual.ts#L12-L19
scalar/packages/api-reference/src/hooks/use-virtual.ts
Lines 12 to 19 in 012c286
| observer.value = new IntersectionObserver( | |
| ([entry]) => { | |
| if (entry?.isIntersecting) { | |
| isVisible.value = true | |
| nextTick(() => { | |
| placeholderHeight.value = el.value?.offsetHeight || 1000 | |
| }) | |
| } |
Scalar References End to End Test ResultsDetails
Failed teststest/snapshots/models.e2e.ts › Scalar Galaxy (Classic Layout) Important These tests include snapshots that may need to be updated if there are intentional changes to the UI components. To update the snapshots run |
Scalar Components Snapshot Test ResultsDetails
|
Scalar CDN Snapshot Diff ResultsDetails
Failed teststest/snapshots-cdn/snapshot.e2e.ts › Diff with CDN - Scalar Galaxy Important These tests detect visual differences between the current PR and the latest CDN build which means they may be affected by other changes in They can help determine if the changes in the PR are causing any unexpected visual regressions but may be less helpful in isolating the exact cause. For more details see the readme. |
Problem
When there is very large tags open we have too many DOM elements to handle elegantly.
Solution
Virtualizes operations with a fixed estimated height and a fairly long render window.
Checklist
I've gone through the following:
pnpm changeset).Note
Lazily renders
Operation.vueusing a newuseVirtualhook that shows a placeholder height and mounts content only when in view.features/Operation/Operation.vue: wraps layouts in a container withref="virtual", appliesminHeightfromplaceholderHeight, and conditionally renders whenisVisibleusinguseTemplateRefanduseVirtual.ClassicLayoutandModernLayoutrendering paths behind visibility check.hooks/use-virtual.ts: addsuseVirtualusingIntersectionObserver(largerootMargin) to exposeisVisibleandplaceholderHeightfor lazy mounting.Written by Cursor Bugbot for commit 012c286. This will update automatically on new commits. Configure here.