Skip to content

Commit

Permalink
Refactor and improve auto size estimation
Browse files Browse the repository at this point in the history
  • Loading branch information
inokawa committed Feb 13, 2024
1 parent f65e848 commit e9831d5
Showing 1 changed file with 22 additions and 25 deletions.
47 changes: 22 additions & 25 deletions src/core/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,20 +109,6 @@ export const overscanEndIndex = (
return min(endIndex, count - 1);
};

const calculateJump = (
cache: Cache,
items: readonly ItemResize[],
keepEnd?: boolean
): number => {
return items.reduce((acc, [index, size]) => {
const diff = size - getItemSize(cache, index);
if (!keepEnd || diff > 0) {
acc += diff;
}
return acc;
}, 0);
};

type Subscriber = (sync?: boolean) => void;

type StateVersion = readonly [];
Expand Down Expand Up @@ -301,34 +287,45 @@ export const createVirtualStore = (
break;
}

// Calculate jump
// Should maintain visible position to minimize junks in appearance
let diff: number;
let measuredSizeDiff = 0;
let shouldKeepStart = false;
let shouldStickToEnd = false;
if (_scrollMode === SCROLL_BY_SHIFT) {
if (scrollOffset > getMaxScrollOffset() - SUBPIXEL_THRESHOLD) {
// Keep end to stick to the end
diff = calculateJump(cache, updated, true);
shouldStickToEnd = true;
} else {
// Keep distance from end immediately after prepending
// We can assume jumps occurred on the upper outside
diff = calculateJump(cache, updated);
}
} else {
// Keep start at mid
diff = calculateJump(
cache,
updated.filter(([index]) => getItemOffset(index) < scrollOffset)
);
shouldKeepStart = true;
}
applyJump(diff);

// Update item sizes
for (const [index, size] of updated) {
if (setItemSize(cache, index, size) && shouldAutoEstimateItemSize) {
const prevSize = getItemSize(cache, index);
const isInitialMeasurement = setItemSize(cache, index, size);
// Calculate jump
// Should maintain visible position to minimize junks in appearance
if (!shouldKeepStart || getItemOffset(index) < scrollOffset) {
const diff = size - prevSize;
if (!shouldStickToEnd || diff > 0) {
measuredSizeDiff += diff;
}
}

if (shouldAutoEstimateItemSize) {
_totalMeasuredSize += size;
if (!isInitialMeasurement) {
_totalMeasuredSize -= prevSize;
}
}
}

applyJump(measuredSizeDiff);

// Estimate initial item size from measured sizes
if (
shouldAutoEstimateItemSize &&
Expand Down

0 comments on commit e9831d5

Please sign in to comment.