I’m building a drag and drop WYSIWYG editor where components can be added to and arranged on a page
Each component is wrapped in a layout box that saves the position and size and these layouts are stored in a collection.
Currently the code responsible for providing ‘snapping’ functionality (to page bounds and other layouts including center/edge alignments) maps over that collection to build the lines to snap to.
For that snapping code to work, each layout must always be up to date in the collection when a user starts dragging or resizing a layout. This can end up being a lot of database updates. (Current code updates for each
mousemove but I already worked out that doesn’t provide any benefit for a heck of a lot of network requests)
Is there a simple solution that allows me to rapidly modify the local collection and occasionally save to the server?
Does this need to be based on pub/sub? More specifically, in your use case, do other users edit the same data as well at the same time and do you need changes from one user to propagate to other users in a more or less real-time fashion during the editing? If not, then you could push all the relevant data via a method to the client into a local variable/store and have the UI update off of that, essentially bypassing minimongo. Then each time a user makes a change client-side, only the local variable is updated. And finally when the user hits the save button, the changes will just be sent from the local variable/store back to the server via another method. Probably not the simplest thing to implement, especially since you’d likely also need to implement a locking feature to avoid users messing with each others’ data, but still fairly straight forward I’d say. This is something I have done for just plain forms and it works fine.
Alternatively, you could keep using the pub/sub but as such that changes are only saved to the database when the user lets go of the box (presumably mouseup) and during mousemove the snapping feature (well, esentially collision detection) is done based on local variables with the position data of other boxes that you have populated at the start of dragging (presumably mousedown) instead of hammering at minimongo during mousemove. If there is a risk that some other user may have moved a box while a user is in the middle of the mousemove event (i.e. the collision data gathered at the start of the mousedown-mousemove-mouseup cycle may have been invalidated), then you could just do another collision detection check at the end of the drag during the mouseup event with updated data. I have a fairly complex UI working like this and I’m happy with it.
Finally, even if it’s possible to mitigate the performance issues with something similar to DDPRateLimiter, I’d still be sceptical about using the pub/sub mechanisms directly with the mousemove listener. Simply because of the overhead that will likely come with it. I’d recommend keeping anything behind mousemove as lean as you possibly can.