I have a problem with a specific use-case
where my application can call store.commit
3 times or more
in a second and those making the application lag or freeze the browser.
So what I though was, can I buffer state changes
before actually commit the changes and update view.
For the first question that I'm not clear about are, does vue update it's view on every state changes or not?
For example I have the following code
state = {
// Here i was using object instead of array of object
// so I can get into my target object instead of
// finding my target object first
rooms: {
1: { id: 1, name: 'Room 1' },
2: { id: 2, name: 'Room 2' },
3: { id: 3, name: 'Room 3' }
}
}
mutations: {
setRoom(state, payload) {
const id = payload.id
const oldData = state.rooms[id]
const newData = Object.assign({}, oldData, payload.room)
Vue.set(state.rooms, id, newData)
}
}
actions: {
updateRoom(store, { roomId, patch }) {
store.commit('setRoom', { id: roomId, room: patch })
}
}
// And later
store.dispatch('updateRoom', { roomId: 1, patch: { name: 'Room 11' } })
store.dispatch('updateRoom', { roomId: 2, patch: { name: 'Room 22' } })
store.dispatch('updateRoom', { roomId: 3, patch: { name: 'Room 33' } })
// Those store.dispatch come from a websocket and possible to have
// custom `patch` data
For the second question, if the above code update 3 times. Is there a way to buffer the changes or update the view only once?
So instead of doing change state 3 times first changes
{
rooms: {
1: { id: 1, name: 'Room 11' },
2: { id: 2, name: 'Room 2' },
3: { id: 3, name: 'Room 3' }
}
}
second changes
{
rooms: {
1: { id: 1, name: 'Room 11' },
2: { id: 2, name: 'Room 22' },
3: { id: 3, name: 'Room 3' }
}
}
third changes
{
rooms: {
1: { id: 1, name: 'Room 11' }
2: { id: 2, name: 'Room 22' },
3: { id: 3, name: 'Room 33' }
}
}
Can it become only one changes happend? Like
{
rooms: {
1: { id: 1, name: 'Room 11' }
2: { id: 2, name: 'Room 22' },
3: { id: 3, name: 'Room 33' }
}
}
From https://v2.vuejs.org/v2/guide/reactivity.html#Async-Update-Queue:
Whenever a data change is observed, (Vue) will open a queue and buffer all the data changes that happen in the same event loop. If the same watcher is triggered multiple times, it will be pushed into the queue only once. (...) Then, in the next event loop “tick”, Vue flushes the queue and performs the actual (already de-duped) work.
So... don't worry about it, Vue is already taking care of it.
And why don't you use an array? Assuming that all room IDs are in a secuential order starting with 1, you can instantly access Room 1
in rooms[0]
, Room 2
in rooms[1]
and so on, and accesing an array by index will be faster than accessing an object by key.