Skip to content

Commit cf35b35

Browse files
committed
fix(perf): skip update if the user hasn't scrolled more than min item height
1 parent 2ab6d6a commit cf35b35

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

src/components/RecycleScroller.vue

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,19 @@ export default {
136136
const items = this.items
137137
const field = this.sizeField
138138
const minItemSize = this.minItemSize
139+
let computedMinSize = 10000
139140
let accumulator = 0
140141
let current
141142
for (let i = 0, l = items.length; i < l; i++) {
142143
current = items[i][field] || minItemSize
144+
if (current < computedMinSize) {
145+
computedMinSize = current
146+
}
143147
accumulator += current
144148
sizes[i] = { accumulator, size: current }
145149
}
150+
// eslint-disable-next-line
151+
this.$_computedMinItemSize = computedMinSize
146152
return sizes
147153
}
148154
return []
@@ -175,6 +181,7 @@ export default {
175181
this.$_views = new Map()
176182
this.$_unusedViews = new Map()
177183
this.$_scrollDirty = false
184+
this.$_lastUpdateScrollPosition = 0
178185
179186
// In SSR mode, we also prerender the same number of item for the first render
180187
// to avoir mismatch between server and client templates
@@ -245,7 +252,7 @@ export default {
245252
this.$_scrollDirty = true
246253
requestAnimationFrame(() => {
247254
this.$_scrollDirty = false
248-
const { continuous } = this.updateVisibleItems(false)
255+
const { continuous } = this.updateVisibleItems(false, true)
249256
250257
// It seems sometimes chrome doesn't fire scroll event :/
251258
// When non continous scrolling is ending, we force a refresh
@@ -270,8 +277,9 @@ export default {
270277
}
271278
},
272279
273-
updateVisibleItems (checkItem) {
280+
updateVisibleItems (checkItem, checkPositionDiff = false) {
274281
const itemSize = this.itemSize
282+
const minItemSize = this.$_computedMinItemSize
275283
const typeField = this.typeField
276284
const keyField = this.simpleArray ? null : this.keyField
277285
const items = this.items
@@ -291,6 +299,18 @@ export default {
291299
totalSize = null
292300
} else {
293301
const scroll = this.getScroll()
302+
303+
// Skip update if use hasn't scrolled enough
304+
if (checkPositionDiff) {
305+
let positionDiff = scroll.start - this.$_lastUpdateScrollPosition
306+
if (positionDiff < 0) positionDiff = -positionDiff
307+
if ((itemSize === null && positionDiff < minItemSize) || positionDiff < itemSize) {
308+
return {
309+
continuous: false,
310+
}
311+
}
312+
}
313+
294314
const buffer = this.buffer
295315
scroll.start -= buffer
296316
scroll.end += buffer

0 commit comments

Comments
 (0)