forked from cybrespace/pinafore
implement batchUpdate()
This commit is contained in:
parent
0f69df592a
commit
bfe0f1255a
|
@ -21,44 +21,20 @@
|
||||||
<script>
|
<script>
|
||||||
import { virtualListStore } from '../_utils/virtualListStore'
|
import { virtualListStore } from '../_utils/virtualListStore'
|
||||||
import { AsyncLayout } from '../_utils/AsyncLayout'
|
import { AsyncLayout } from '../_utils/AsyncLayout'
|
||||||
import { mark, stop } from '../_utils/marks'
|
|
||||||
|
|
||||||
let updateItemHeights = {}
|
|
||||||
let promise = Promise.resolve()
|
|
||||||
|
|
||||||
const asyncLayout = new AsyncLayout(node => node.getAttribute('virtual-list-key'))
|
const asyncLayout = new AsyncLayout(node => node.getAttribute('virtual-list-key'))
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
oncreate() {
|
oncreate() {
|
||||||
let key = this.get('key')
|
let key = this.get('key')
|
||||||
// TODO: implement batchUpdate
|
|
||||||
// TODO: fix resize on media
|
|
||||||
asyncLayout.observe(key, this.refs.node, (rect) => {
|
asyncLayout.observe(key, this.refs.node, (rect) => {
|
||||||
updateItemHeights[key] = rect.height
|
// update all item heights in one microtask batch for better perf
|
||||||
promise = promise.then(() => {
|
this.store.batchUpdate('itemHeights', key, rect.height)
|
||||||
// update all item heights in one microtask batch for better perf
|
|
||||||
let updatedKeys = Object.keys(updateItemHeights)
|
|
||||||
if (!updatedKeys.length) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mark('batch update VirtualListItem')
|
|
||||||
// batch all updates to itemHeights for better perf
|
|
||||||
let itemHeights = this.store.get('itemHeights')
|
|
||||||
for (key of updatedKeys) {
|
|
||||||
itemHeights[key] = updateItemHeights[key]
|
|
||||||
}
|
|
||||||
this.store.set({
|
|
||||||
itemHeights: itemHeights
|
|
||||||
})
|
|
||||||
updateItemHeights = {}
|
|
||||||
stop('batch update VirtualListItem')
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
ondestroy() {
|
ondestroy() {
|
||||||
let key = this.get('key')
|
let key = this.get('key')
|
||||||
asyncLayout.unobserve(key, this.refs.node)
|
asyncLayout.unobserve(key, this.refs.node)
|
||||||
delete updateItemHeights[key]
|
|
||||||
},
|
},
|
||||||
store: () => virtualListStore,
|
store: () => virtualListStore,
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -2,6 +2,35 @@ import { Store } from 'svelte/store.js'
|
||||||
import { mark, stop } from '../_utils/marks'
|
import { mark, stop } from '../_utils/marks'
|
||||||
|
|
||||||
class VirtualListStore extends Store {
|
class VirtualListStore extends Store {
|
||||||
|
constructor(obj) {
|
||||||
|
super(obj)
|
||||||
|
this._batches = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
batchUpdate(key, subKey, value) {
|
||||||
|
let batch = this._batches[key]
|
||||||
|
if (!batch) {
|
||||||
|
batch = this._batches[key] = {}
|
||||||
|
}
|
||||||
|
batch[subKey] = value
|
||||||
|
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
let updatedKeys = Object.keys(batch)
|
||||||
|
if (!updatedKeys.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mark('batchUpdate()')
|
||||||
|
let obj = this.get(key)
|
||||||
|
for (let otherKey of updatedKeys) {
|
||||||
|
obj[otherKey] = batch[otherKey]
|
||||||
|
}
|
||||||
|
delete this._batches[key]
|
||||||
|
let toSet = {}
|
||||||
|
toSet[key] = obj
|
||||||
|
this.set(toSet)
|
||||||
|
stop('batchUpdate()')
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const virtualListStore = new VirtualListStore({
|
const virtualListStore = new VirtualListStore({
|
||||||
|
|
Loading…
Reference in New Issue