Skip to content

Commit 06b9e3e

Browse files
committed
Prolong zone range size to achive better performance.
1 parent ec1f00c commit 06b9e3e

File tree

1 file changed

+60
-41
lines changed

1 file changed

+60
-41
lines changed

index.js

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -27,29 +27,29 @@
2727
onscroll: Function
2828
},
2929

30-
// An object helping to calculate.
31-
delta: {
32-
start: 0, // Start index.
33-
end: 0, // End index.
34-
total: 0, // All items count.
35-
keeps: 0, // Nums of item keeping in real dom.
36-
viewHeight: 0, // Container wrapper viewport height.
37-
allPadding: 0, // All padding of not-render-yet doms.
38-
paddingTop: 0, // Container wrapper real padding-top.
39-
scrollTop: 0, // Store scrollTop.
40-
scrollDirect: 'd', // Scroll direction.
41-
fireTime: 0 // Store last event time avoiding compact fire.
30+
created: function () {
31+
// An object helping to calculate.
32+
this.delta = {
33+
start: 0, // Start index.
34+
end: 0, // End index.
35+
total: 0, // All items count.
36+
keeps: 0, // Nums keeping in real dom.
37+
benchs: 0, // Nums scroll pass should force update.
38+
scrollTop: 0, // Store scrollTop.
39+
scrollDirect: 'd', // Scroll direction.
40+
viewHeight: 0, // Container wrapper viewport height.
41+
allPadding: 0, // All padding of not-render-yet doms.
42+
paddingTop: 0, // Container wrapper real padding-top.
43+
timeStamp: 0 // Last event fire timestamp avoid compact fire.
44+
}
4245
},
4346

4447
watch: {
4548
start: function (index) {
46-
var delta = this.$options.delta
49+
var delta = this.delta
4750

48-
if (index !== parseInt(index, 10)) {
49-
return console.warn(innerns + ': start ' + index + ' is not integer.')
50-
}
51-
if (index < 0 || index > delta.total - 1) {
52-
return console.warn(innerns + ': start ' + index + ' is overflow.')
51+
if (!this.validStart(index)) {
52+
return
5353
}
5454

5555
var start, end, scrollTop
@@ -85,7 +85,7 @@
8585
},
8686

8787
updateZone: function (offset) {
88-
var delta = this.$options.delta
88+
var delta = this.delta
8989
var overs = Math.floor(offset / this.size)
9090

9191
if (!offset && delta.total) {
@@ -95,8 +95,7 @@
9595
delta.scrollDirect = delta.scrollTop > offset ? 'u' : 'd'
9696
delta.scrollTop = offset
9797

98-
// Need moving items at lease one unit height.
99-
// @todo: consider prolong the zone range size.
98+
// Calculate the start and end by moving items.
10099
var start = overs || 0
101100
var end = overs ? (overs + delta.keeps) : delta.keeps
102101

@@ -106,6 +105,11 @@
106105
start = zone.start
107106
}
108107

108+
// If scroll pass items within now benchs, do not update.
109+
if (overs > delta.start && overs - delta.start <= delta.benchs) {
110+
return
111+
}
112+
109113
delta.end = end
110114
delta.start = start
111115

@@ -115,7 +119,7 @@
115119

116120
// Avoid overflow range.
117121
isOverflow: function (start) {
118-
var delta = this.$options.delta
122+
var delta = this.delta
119123
var overflow = delta.total - delta.keeps > 0 && (start + this.remain >= delta.total)
120124
if (overflow && delta.scrollDirect === 'd') {
121125
this.fireEvent('tobottom')
@@ -125,21 +129,32 @@
125129

126130
// Fire a props event to parent.
127131
fireEvent: function (event) {
128-
var cb = this[event]
129132
var now = +new Date()
130-
var delta = this.$options.delta
131-
if (cb && (now - delta.fireTime > 35)) {
132-
cb()
133-
delta.fireTime = now
133+
if (this[event] && now - this.delta.timeStamp > 30) {
134+
this[event]()
135+
this.delta.timeStamp = now
134136
}
135137
},
136138

139+
// Check if given start is valid.
140+
validStart: function (start) {
141+
let valid = 1
142+
if (start !== parseInt(start, 10)) {
143+
valid = 0
144+
console.warn(innerns + ': start ' + start + ' is not an integer.')
145+
}
146+
if (start < 0 || start > this.delta.total - 1) {
147+
valid = 0
148+
console.warn(innerns + ': start ' + start + ' is an overflow index.')
149+
}
150+
return !!valid
151+
},
152+
137153
// If overflow range return the last zone.
138154
getLastZone: function () {
139-
var delta = this.$options.delta
140155
return {
141-
end: delta.total,
142-
start: delta.total - delta.keeps
156+
end: this.delta.total,
157+
start: this.delta.total - this.delta.keeps
143158
}
144159
},
145160

@@ -148,8 +163,9 @@
148163
this.$refs.container.scrollTop = scrollTop
149164
},
150165

166+
// Filter the shown items base on start and end.
151167
filter: function (slots) {
152-
var delta = this.$options.delta
168+
var delta = this.delta
153169

154170
if (!slots) {
155171
slots = []
@@ -167,23 +183,26 @@
167183
},
168184

169185
beforeMount: function () {
170-
var remains = this.remain
171-
var delta = this.$options.delta
172-
var benchs = Math.round(remains / 2)
173-
174-
delta.start = this.start >= remains ? this.start : 0
175-
delta.end = this.start + remains + benchs
176-
delta.keeps = remains + benchs
177-
delta.viewHeight = this.size * remains
186+
var delta = this.delta
187+
var remain = this.remain
188+
var benchs = Math.round(remain / 2)
189+
190+
delta.benchs = benchs
191+
delta.keeps = remain + benchs
192+
delta.viewHeight = this.size * remain
193+
delta.start = this.start >= remain ? this.start : 0
194+
delta.end = this.start + remain + benchs
178195
},
179196

180197
mounted: function () {
181-
this.setScrollTop(this.start * this.size)
198+
if (this.validStart(this.start)) {
199+
this.setScrollTop(this.start * this.size)
200+
}
182201
},
183202

184203
render: function (createElement) {
185204
var showList = this.filter(this.$slots.default)
186-
var delta = this.$options.delta
205+
var delta = this.delta
187206

188207
return createElement(this.rtag, {
189208
'ref': 'container',

0 commit comments

Comments
 (0)