Skip to content

feat(virtual-core): skip sync DOM read in measureElement when cached size exists#1183

Merged
piecyk merged 1 commit into
TanStack:mainfrom
piecyk:damian/feat/skip-sync-measure-on-cached-size
Jun 2, 2026
Merged

feat(virtual-core): skip sync DOM read in measureElement when cached size exists#1183
piecyk merged 1 commit into
TanStack:mainfrom
piecyk:damian/feat/skip-sync-measure-on-cached-size

Conversation

@piecyk
Copy link
Copy Markdown
Collaborator

@piecyk piecyk commented Jun 1, 2026

This PR skip synchronous DOM reads (offsetWidth/offsetHeight) in the default measureElement when a cached size already exists.

Reading offsetWidth/offsetHeight forces browser layout reflow. On re-renders, this is redundant, the ResizeObserver is already watching the element and will fire if the size changes.

🎯 Changes

This PR skips the sync DOM read when the item already has a measured size in itemSizeCache, returning the cached value instead. The ResizeObserver is already observing the element and will deliver an accurate size asynchronously if it changed. First mount still does the sync read since no cache exists yet.

itemSizeCache is made public so the standalone measureElement function can access it (same pattern as the existing public elementsCache). Users who need sync DOM reads on every render can pass a custom measureElement.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Refactor
    • Improved rendering performance by reusing cached element sizes to avoid unnecessary synchronous DOM reads and reduce layout reflows during re-renders.
    • Made the internal item-size cache accessible, allowing advanced users to inspect and manage cached measurements for fine-grained control and debugging.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e5b46050-4fe6-4598-bace-493f69566cd5

📥 Commits

Reviewing files that changed from the base of the PR and between b1f6f19 and 3c51175.

📒 Files selected for processing (2)
  • .changeset/skip-sync-measure-cached.md
  • packages/virtual-core/src/index.ts
✅ Files skipped from review due to trivial changes (1)
  • .changeset/skip-sync-measure-cached.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/virtual-core/src/index.ts

📝 Walkthrough

Walkthrough

The Virtualizer exposes its element size cache publicly and updates measureElement to return cached sizes during synchronous measurement calls instead of immediately performing offsetWidth/offsetHeight reads.

Changes

Measurement Cache Optimization

Layer / File(s) Summary
Public cache field
packages/virtual-core/src/index.ts
itemSizeCache visibility is changed from private to public, allowing external access to the size cache map.
Cache-reading measurement path
packages/virtual-core/src/index.ts, .changeset/skip-sync-measure-cached.md
measureElement now checks the cache first when invoked without a ResizeObserverEntry, returning the cached size instead of reading offsetWidth/offsetHeight synchronously; a changeset documents the behavior and patch bump.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested reviewers

  • tannerlinsley

Poem

🐰 I found a map of sizes, snug and neat,
I peeked inside and skipped the noisy beat,
No layout thrash, no frantic reflow race,
The virtual meadow kept its gentle pace,
Hoppity hops, I bless the cached space ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically summarizes the main change: skipping synchronous DOM reads in measureElement when a cached size exists.
Description check ✅ Passed The description follows the template structure with all required sections completed: changes explained, checklist items marked, and release impact confirmed with changeset.
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.

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

✨ 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 and usage tips.

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Jun 1, 2026

View your CI Pipeline Execution ↗ for commit 3c51175

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 2m 25s View ↗
nx run-many --target=build --exclude=examples/** ✅ Succeeded 17s View ↗

☁️ Nx Cloud last updated this comment at 2026-06-02 03:36:38 UTC

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jun 1, 2026

More templates

@tanstack/angular-virtual

npm i https://pkg.pr.new/@tanstack/angular-virtual@1183

@tanstack/lit-virtual

npm i https://pkg.pr.new/@tanstack/lit-virtual@1183

@tanstack/react-virtual

npm i https://pkg.pr.new/@tanstack/react-virtual@1183

@tanstack/solid-virtual

npm i https://pkg.pr.new/@tanstack/solid-virtual@1183

@tanstack/svelte-virtual

npm i https://pkg.pr.new/@tanstack/svelte-virtual@1183

@tanstack/virtual-core

npm i https://pkg.pr.new/@tanstack/virtual-core@1183

@tanstack/vue-virtual

npm i https://pkg.pr.new/@tanstack/vue-virtual@1183

commit: 3c51175

@piecyk piecyk force-pushed the damian/feat/skip-sync-measure-on-cached-size branch from b1f6f19 to 3c51175 Compare June 2, 2026 03:33
@piecyk piecyk merged commit c0b84c8 into TanStack:main Jun 2, 2026
10 checks passed
@github-actions github-actions Bot mentioned this pull request Jun 2, 2026
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