Measurement and dynamic sizes

The model starts with estimatedItemSize so it can calculate a range before any item exists in the DOM. After an item mounts, the adapter attaches its element and core measures the border box with ResizeObserver.

1 · Estimate

Core calculates the first range and scrollbar without waiting for DOM.

2 · Measure

Mounted items report their real border-box size.

3 · Correct

Core updates offsets and preserves the visible anchor or list end.

Choose an estimate close to the common item size. It does not need to be exact; better estimates simply reduce correction work before enough rows have been measured.

Use the framework’s item binding

Every mounted virtual item must be associated with its current index. The exact syntax is intentionally kept in the runnable variable-size examples:

Do not read clientHeight, clientWidth, or getBoundingClientRect() in each item renderer. Core owns measurement batching and applies size changes without requiring a framework render when the rendered range stays the same.

When content changes after mount

No manual invalidation is needed for ordinary DOM size changes: the observer remeasures the attached item. Call invalidateItemSizes() only when cached sizes must be forgotten before the browser can report a new layout, such as a renderer whose dimensions change outside observed DOM.

Sticky headers and footers also reserve measured viewport space. Their complete lifecycle is demonstrated in the sticky header and footer example.

If rows appear to jump

  1. Verify that the item binding receives the current index.
  2. Use stable data keys when records can move; see data changes and anchoring.
  3. Improve estimatedItemSize when initial items vary greatly.
  4. Ensure application CSS does not overwrite the layout-owned transform or size properties described in how virtual layout works.