Window & Dynamic Size List Virtualization Causes Mobile Safari IOS Scroll Momentum Interruption
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.1k
- Forks
- 466
- Avg merge
- 2d 31m
- Merged PRs (30d)
- 13
Description
Describe the bug
By using the useWindowVirtualizer hook to apply virtualization for list items with different heights in relation to window scrolling, when you scroll, the virtualization behavior will occur.
Items that no longer need to be rendered will disappear from the DOM, and the list items corresponding to the visible indices will begin to appear in the DOM.
On Mobile iOS Safari, momentum scrolling triggered by user gestures works, but when combined with virtualization, the momentum effect fails to end smoothly and instead stutters or breaks abruptly. Is there a way to resolve this issue?
import "./styles.css";
import { useWindowVirtualizer } from "@tanstack/react-virtual";
const createRandomHeights = (
min: number,
max: number,
count: number = 1000
) => {
const heights = [];
for (let i = 0; i < count; i++) {
heights.push(Math.floor(Math.random() * (max - min + 1) + min));
}
return heights;
};
const randomHeights = createRandomHeights(100, 400);
const colors = ["red", "yellow", "blue"];
export default function App() {
const virtualizer = useWindowVirtualizer({
count: 1000,
estimateSize: () => 400,
overscan: 5,
scrollMargin: 0,
});
const virtualItems = virtualizer.getVirtualItems();
return (
<div>
<div
style={{
height: `${virtualizer.getTotalSize()}px`,
position: "relative",
width: "100%",
}}
>
<div
style={{
transform: `translateY(${
(virtualItems[0]?.start ?? 0) - virtualizer.options.scrollMargin
}px)`,
position: "absolute",
left: "0",
top: "0",
width: "100%",
}}
>
{virtualItems.map((virtualItem) => {
return (
<div
key={virtualItem.key}
data-index={virtualItem.index}
ref={virtualizer.measureElement}
style={{
paddingTop: "40px",
}}
>
<div
style={{
height: randomHeights[virtualItem.index],
backgroundColor: colors[virtualItem.index % 3],
}}
></div>
</div>
);
})}
</div>
</div>
</div>
);
}
Your minimal, reproducible example
https://codesandbox.io/p/sandbox/qhkvyz
Steps to reproduce
- Go to CodeSandbox Link
- Scroll down Preview Page
- As you scroll, the momentum scroll stops occurring and the scrolling becomes increasingly choppy.
Expected behavior
I hope to maintain a seamless momentum scroll experience.
How often does this bug happen?
Every time
Screenshots or Videos
https://github.com/user-attachments/assets/2b27fcd6-e3de-449b-ac20-2633d76619d3
https://github.com/user-attachments/assets/166be2b0-cab1-495a-a9e1-9b770e31c1fc
Platform
- OS: IOS
- Browser: Safari
- Version: 18.1, 17.6.1
tanstack-virtual version
v3.10.6
TypeScript version
v5.4.5
Additional context
It seems that the CodeSandbox link is difficult to run on Mobile iOS Safari at the moment. However, you can reproduce the issue by running the attached source code.
Terms & Code of Conduct
- I agree to follow this project's Code of Conduct
- I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the provided CodeSandbox reproduction and the useWindowVirtualizer example, testing it on Mobile iOS Safari with dynamically sized items. Investigate the interaction between measured elements being virtualized and window-scroll momentum; done means the reproduction retains smooth momentum scrolling while virtualization remains active.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100