Skip to content

Commit 1d8c733

Browse files
committed
Optimize scrollTo for non animated situations
1 parent 349124a commit 1d8c733

File tree

1 file changed

+37
-23
lines changed

1 file changed

+37
-23
lines changed

src/recyclerview/hooks/useRecyclerViewController.tsx

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,13 @@ export function useRecyclerViewController<T>(
152152
async (offset: number): Promise<void> => {
153153
return new Promise((resolve) => {
154154
// TODO: Make sure we don't scroll beyond content size
155-
recyclerViewManager.updateScrollOffset(offset);
156-
// Add the resolve function to the queue
157-
pendingScrollResolves.current.push(resolve);
158-
setRenderId((prev) => prev + 1);
155+
if (recyclerViewManager.updateScrollOffset(offset) !== undefined) {
156+
// Add the resolve function to the queue
157+
pendingScrollResolves.current.push(resolve);
158+
setRenderId((prev) => prev + 1);
159+
} else {
160+
resolve();
161+
}
159162
});
160163
},
161164
[recyclerViewManager]
@@ -355,20 +358,21 @@ export function useRecyclerViewController<T>(
355358

356359
const bufferForCompute = bufferForScroll * 2;
357360

361+
if (finalOffset > lastScrollOffset) {
362+
lastScrollOffset = Math.max(
363+
finalOffset - bufferForCompute,
364+
lastScrollOffset
365+
);
366+
recyclerViewManager.setScrollDirection("forward");
367+
} else {
368+
lastScrollOffset = Math.min(
369+
finalOffset + bufferForCompute,
370+
lastScrollOffset
371+
);
372+
recyclerViewManager.setScrollDirection("backward");
373+
}
374+
358375
if (animated) {
359-
if (finalOffset > lastScrollOffset) {
360-
lastScrollOffset = Math.max(
361-
finalOffset - bufferForCompute,
362-
lastScrollOffset
363-
);
364-
recyclerViewManager.setScrollDirection("forward");
365-
} else {
366-
lastScrollOffset = Math.min(
367-
finalOffset + bufferForCompute,
368-
lastScrollOffset
369-
);
370-
recyclerViewManager.setScrollDirection("backward");
371-
}
372376
// go from finalOffset to lastScrollOffset in 5 steps
373377
for (let i = 0; i < 5; i++) {
374378
if (isUnmounted.current) {
@@ -378,21 +382,31 @@ export function useRecyclerViewController<T>(
378382
finalOffset + (lastScrollOffset - finalOffset) * (i / 4)
379383
);
380384
}
381-
finalOffset = getFinalOffset();
382-
const maxOffset = recyclerViewManager.getMaxScrollOffset();
383-
384-
if (finalOffset > maxOffset) {
385-
finalOffset = maxOffset;
385+
} else {
386+
// go from lastScrollOffset to finalOffset in 5 steps
387+
for (let i = 0; i < 5; i++) {
388+
if (isUnmounted.current) {
389+
return;
390+
}
391+
await updateScrollOffsetAsync(
392+
lastScrollOffset + (finalOffset - lastScrollOffset) * (i / 4)
393+
);
386394
}
395+
}
396+
finalOffset = getFinalOffset();
397+
const maxOffset = recyclerViewManager.getMaxScrollOffset();
387398

399+
if (finalOffset > maxOffset) {
400+
finalOffset = maxOffset;
401+
}
402+
if (animated) {
388403
// We don't need to add firstItemOffset here as it will be added in scrollToOffset
389404
handlerMethods.scrollToOffset({
390405
offset: lastScrollOffset,
391406
animated: false,
392407
skipFirstItemOffset: false,
393408
});
394409
}
395-
396410
handlerMethods.scrollToOffset({
397411
offset: finalOffset,
398412
animated,

0 commit comments

Comments
 (0)