I am doing a Kaban project, There are a crashes in the WebSocket(liveview) this happens whenever I make a large data request to be shown on front-end, for example, I made a list of 1000 contacts. When that happens, my handle_event( ) take a long time to respond to return the diff content. I want to know how I can optimize, so that LiveSocket doesn’t crash anymore. Help me, please .
There are various tactics, but they depend a bit on some details. Can you provide more information?
Of course. if i return all my contacts (which are 1000 cards), my handle_events will start to take longer to respond. But if I cut the list of contacts in half, everything starts to flow very well. I realized that this happens when I increase the amount of information to be shown on the screen. Imagine Trello, that in a list there are 1000 cards, but if you try to move some of these cards, everything starts to slow down, but the event is concluded. It is a matter of having stability in the information traffic on the websocket, which I am not understanding.
By details I guess I had in mind some code, or perhaps some metrics. What’s the size of the HTML source that is ultimately generated in bytes? You mention handle event, what triggers the event? What processing do you do in the event? How often is the event triggered?
Have you tried using something like this: https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#module-dom-patching-and-temporary-assigns
For example, when i send event to server html content is returned twice. I do 2 nested loops, but it ends up returning me twice the rendering content. I am not able to identify a solution for this
<%= for list <- @lists do %> <div class="list-wrapper" id="<%= list.id %>" data-position="<%= list.posicao %>" phx-hook="List"> <div class="list"> <div class="list-header" phx-hook="ListTitle"> <input class="list-name-input" style="display:<%= if @rename_list == list.id, do: "block", else: "none" %> " autofocus= "true" name="list-title" phx-hook="ListTitle" value="<%= list.titulo %>" data-list_id="<%= list.id %>"></input> <h2 phx-click="rename_list" phx-value-list_id="<%= list.id %>" style="display: <%= if @rename_list == list.id, do: "none", else: "block" %>"><%= list.titulo %></h2> <%= if Enum.empty?(FluxoIdeal.Auto.list_fluxo(list.id)) == false do %> <i phx-click="robot-unique-fluxo" style="color: #6b778c;cursor: pointer;font-size: 12px;" phx-value-show_list_automacao="true" phx-value-unique_list_id="<%= list.id %>" class="fas fa-robot"></i> <% end %> <div class="more-list-actions icons-format"> <i class="material-icons" style="font-size: 18px!important">more_horiz</i> </div> </div> <% dom_id = "list" <> Integer.to_string(list.id) %> <% sorted_cards = Enum.sort(list.cartoes, &(&1.posicao <= &2.posicao)) %> <div class="list-cards" id="<%= dom_id %>" data-list-id="<%= list.id %>" phx-update="append"> <%= for card <- sorted_cards do %> <%= live_component(@socket, FluxoIdealWeb.CardComponent, list_tags: @cartoes_tags, usuario_id: @usuario_id, card: card, list_id: card.lista_id, type_tags: @type_tags) %> <% end %> </div> </div> </div> <% end %>
Usually when this happens to me it’s because I have invalid HTML. I’d run the HTML that shows up in your browser through an HTML validator and make sure that you don’t have duplicate ids, missing tags, etc.
Can you try adding an
id to your
live_component call? Use something unique.
This is what I’m thinking:
A stateless component is always mounted, updated, and rendered whenever the parent template changes. That’s why they are stateless: no state is kept after the component.
However, any component can be made stateful by passing an :id assign.
When i seted a ID in my component, this error appeared:
found duplicate ID “card_component” for component FluxoIdealWeb.CardComponent when rendering template
(phoenix_live_view) lib/phoenix_live_view/diff.ex:392: anonymous fn/5 in Phoenix.LiveView.Diff.render_pending_components/5
What ID did you set? I see you have an
list, which later becomes
card. I suppose
card.id should be unique.
Right, this is key. @Matheus each instance of the component needs a unique ID.
This is solved my problem, thanks guys
So, the final results are these:
But I feel that my diff still takes a long time to respond, and that brings me a little delay after I run an event on the screen.
I see in the first post you are talking about 1000’s of cards. I would observe & benchmark the memory with so many stateful components.
Perhaps also look into some simplifications if possible:
- the nested
forblocks in which you render a component:
- you have an
Enum.sortoperation in the view template, result of which afterwards you use in your
live_component; don’t make it hard for LiveView to track things around, basically;
- look into temporary_assigns