Hi everyone I’m building LiveVue, it’s LiveSvelte rewrite for Vue.
Things are mostly working, but I’m experimenting with one thing. Currently, props are propagated to the frontend as data-props={Jason.encode!(@props)}. It’s working fine, but updating a single prop sends all of them in the update payload. I’m wondering if it could be optimized by splitting props into individual data-vue-prop-[name]=prop.
If I’m correct all data-vue-prop-[name] must be there at compile time to be treated as a static fragment? So, I’d like to create a HEEX macro component that would transform this:
So in other words, there is no way to send only updated props to the frontend?
It’s a bit sad, because it looks like it could be written by hand to achieve a smaller update payload, but there is no easy way to automatically achieve this.
Well in LiveView dynamic updates are limited to {} or <%= %> blocks (mostly). So if I have props={@props} then each time any key updates, the whole expression {@props} is recomputed and sent.
But if I would write key1={@val1} key2={@val2} then these updates are more granular, so change to {@val1} won’t send over unchanged {@val2}.
Since I want to let my users write key1={@val1} key2={@val2} and build these props for them (similar to this file) I was wondering if I could somehow just map these key / values and pass them to the resulting div.
But at compile time you cannot know that there is a key1 or key2 in the first place, because it’s going to be different keys for each call to the function component. So LV needs to send both keys/attributes and their values. I’m not sure if it can optimize for a dynamic key not having changed as well.
If you are rewriting LiveSvelte, I’d advise you checkout live_json. LiveSvelte, mentions it in this section docs and gives an example here. live_json uses json diffs to minimize data transfer.
On your mount, initialize the state:
def mount(_params, _, socket) do
data = get_your_data()
{:ok,
socket
|> LiveJson.initialize("dataviz", data)
}
end
Then, to send updated data:
def handle_info({:new_data_to_visualize, new_data} = _event, socket) do
{:noreply,
socket
|> LiveJson.push_patch("dataviz", new_data)
}
end