When inspecting what’s being passed from the server to the client I realise that more data is sent than what I was expecting for assigns inside a for loop.
I have this code:
<%= for i <- 1..3 do %>
<div class="valueWrap <%= i %>">
<div class="value <%= i %>">
<%= Enum.at(@data, i-1 %>
</div>
<div class="label <%= i %>">
<%= Enum.at(@labels, i-1) %>
</div>
</div>
<%end%>
Where data is a dynamic list like [10, 200, 95]
and labels: ["New orders", "Sales amount", "Satisfaction"]
The only assigns that changes is data. i and id are dynamically built but, for example, labels never changes.
Why are all this assigns sent every time data changes? According to the docs Liveview can track diffs inside a for loop and I was expecting diff to figure it out and only send the updated data.
It does diff tracking in the sense that it won’t re-render the for loop unless @data or @labels changes. If they do change, then it sends the whole block.
This is difficult to do. Enum.with_index could do anything with the data, therefore liveview cannot optimize the resulting code in any way – change tracking is no longer possible. This is documented here: Assigns and LiveEEx templates — Phoenix LiveView v0.15.4
The solution would be to store the list with indexes applied already instead of adding the index in the template.