Hamilton Ulmer

Tools for Data Analysis & Deep Work

Immer patches & websocket-based applications
Feb 5, 2022

tldr: you can send an immer patch from your backend-powered store and apply it in the client instead of shipping all of your state with every user action.

I wrote a bit about “backend application stores” – instead of updating your application state in the frontend, updating it on the server & sending the entire state back to the frontend. In my case, I have a Svelte store and a Redux-like state update model on the backend, and another duplicate Svelte store on the frontend that replicates the backend state. I send the entire state back to the frontend when the backend store updates. Critically, I use immer.js’s core function, produce, for state updates – you describe the next state as a mutation of the current state, and then get a whole new copy. This works well for “local-first” applications because you probably won’t suffer from network issues on your local computer. And if you need to move the store to the frontend, it’s often easy to do so if you abstract any server-specific functions to an API.

THE PROBLEM – What happens if you decide down the line that you need to switch to a remote server? I’m working on a project where we’re considering having multiple build targets beyond just a localhost application, including a wasm-based static verison (i.e. everything in the client) and a traditional remote server. Regarding the remote server, if I’m doing massive data-intensive updates to the store at a rapid clip (maybe up to 100ms distance between two updates) this could really start to fall apart, given that users are expecting low-latency interactions. I’m shipping parts of result sets and data for interactive dataviz, so you can imagine that a serialized version of the entire store could be a few hundred kb per message.

THE SOLUTION – One of my engineers discovered a simple solution – instead of sending the entire state to the frontend store over a websocket, you can send the immer patch, and then apply it on the frontend. One doesn’t have to build a new protocol or force the state update to happen in the frontend – just apply the patch to the Svelte store and update the whole thing at once.