Feathers-vuex: [Question] Optimizing for bulk patch responses and update cycle on the front-end

Created on 20 Sep 2020  路  7Comments  路  Source: feathersjs-ecosystem/feathers-vuex

Hey - What is the recommended way of handling bulk updates on the client-side?

Right now, when I issue a bulk patch request (say adding a new tag to a lot of items) - The request gets executed properly but the update responses from the server make things extremely slow on the client.

So typically, I would issue a request which tells the API to add a tag on items with X,Y,Z ids. The API executes the bulk patch and returns the updated objects of X, Y and Z.

After digging around a bit, I see that the updates get processed one by one as the updated objects are received from the API so, from the front-end perspective, there is not much difference in terms of how the bulk patch works vs issuing individual patch requests for all the items. Is there something that is wrong in my setup or is this the expected behavior?

What would be the right way to handle this without freezing the app when you're updating say 100 or more records?

Thanks!

enhancement

Most helpful comment

So, a little more specific. What I would like to do is update the handleEvent method to gather requests into a queue for each service method.

const eventsByType = {
  created: [],
  updated: [],
  patched: [],
  removed: []
}

Then we can flush the queue on a default (and dynamically customizable per service) timeout of 0 or something really small. We can then use the bulk mutations to handle each of the lists. You can see how this is done in the current feathers-batch client code.

All 7 comments

I faced the same issue. I think the problem is that bulkOperations end up with the mutations addItem, updateItem, removeItem asynchronously which leads to many GUI updates. But I'm not quite sure. Am I right?
I think an approach that can help is to debounce or throttle incoming events. But I guess custom event handling could become a problem with this.
If I got some time I will investigate more into this.

Yes, exactly - Think this question on Vue Forums touches the topic as well https://forum.vuejs.org/t/over-reacting-to-multiple-vuex-mutations/9285

From what I understand- every incoming message from the server gets processed and triggers the whole update cycle across the app.

For example, In my feathers-mongoose setup - Let's say you have a list of 1000 items that you want to set as "archived" - Triggering this kind of patch request on feathers backend results in 1000 patch events with the individual results, which are then published through the channels to all the users who have access to those items. Then, on the client-side - 1000 patched events are received one by one and processed - This results in 1000 mutations and update cycles.

What I am not sure about is, whether it's something in my setup that is the underlying cause of the UI getting almost stuck while this happens or not. Will try to create a clean minimal setup and drill down into this further.

The quickest and dirtyest solution should be to skip the event on the server side: https://docs.feathersjs.com/api/hooks.html#context-status code
Add an before-patch hook wich sets 'context.events' to null if 'id' is null.

Maybe that's an option for you

We still need the changes to be reflected on the clients.
The solution IMO would be to handle multiple items in one event because currently, 1 event = 1 item.
But then we would need to change how channels and events are handled.

The new feathers-batch coming out later today (technically already released on npm) is guiding how I'm going to focus on supporting bulk records going forward. Its client plugin uses an internal timeout to gather requests from anywhere in the app and automatically combine them into a batch. I would like to implement a similar system for processing batches of received events.

So, a little more specific. What I would like to do is update the handleEvent method to gather requests into a queue for each service method.

const eventsByType = {
  created: [],
  updated: [],
  patched: [],
  removed: []
}

Then we can flush the queue on a default (and dynamically customizable per service) timeout of 0 or something really small. We can then use the bulk mutations to handle each of the lists. You can see how this is done in the current feathers-batch client code.

You mean like so? #537 馃槃
It's not quite finished yet. I want to find a better place for the debounceMap and add more tests.
Just to let you know I'm working on it.

@marshallswain Let me know what you think of it. If you want to make this on your own and differently, let me know! You're welome to close the PR then.

Was this page helpful?
0 / 5 - 0 ratings