Skip to content

Commit

Permalink
Merge pull request #471 from inokawa/remove-timeout
Browse files Browse the repository at this point in the history
Improve timeout handling on imperative scroll when document is inactive
  • Loading branch information
inokawa authored Jul 12, 2024
2 parents a5eb22f + 2581c08 commit f2de1ad
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/core/scroller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,19 @@ export const createScroller = (
const waitForMeasurement = (): [Promise<void>, () => void] => {
// Wait for the scroll destination items to be measured.
// The measurement will be done asynchronously and the timing is not predictable so we use promise.
// For example, ResizeObserver may not fire when window is not visible.
let queue: (() => void) | undefined;
return [
new Promise<void>((resolve, reject) => {
queue = resolve;
// Reject when items around scroll destination completely measured
timeout((cancelScroll = reject), 150);
cancelScroll = reject;

// Resize event may not happen when the window/tab is not visible, or during browser back in Safari.
// We have to wait for the initial measurement to avoid failing imperative scroll on mount.
// https://github.com/inokawa/virtua/issues/450
if (store._isInitialMeasurementDone()) {
// Reject when items around scroll destination completely measured
timeout(reject, 150);
}
}),
store._subscribe(UPDATE_SIZE_EVENT, () => {
queue && queue();
Expand Down
4 changes: 4 additions & 0 deletions src/core/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export type VirtualStore = {
_getCacheSnapshot(): CacheSnapshot;
_getRange(): ItemsRange;
_isUnmeasuredItem(index: number): boolean;
_isInitialMeasurementDone(): boolean;
_hasUnmeasuredItemsInFrozenRange(): boolean;
_getItemOffset(index: number): number;
_getItemSize(index: number): number;
Expand Down Expand Up @@ -216,6 +217,9 @@ export const createVirtualStore = (
_isUnmeasuredItem(index) {
return cache._sizes[index] === UNCACHED;
},
_isInitialMeasurementDone() {
return !!viewportSize;
},
_hasUnmeasuredItemsInFrozenRange() {
if (!_frozenRange) return false;
return cache._sizes
Expand Down

0 comments on commit f2de1ad

Please sign in to comment.