kuon
I am using live view to render a table:
<table>
<thead>
<tr>
<th>#</th>
<%= for c <- @columns do %>
<th>
<%= tr(c.display_name, 32) %>
</th>
<% end %>
<th></th>
</tr>
</thead>
<tbody>
<%= for {r, rnum} <- @rows_index do %>
<tr class="<%= if rnum == @selected_y do "selected" end %>">
<td><%= rnum + 1 %></td>
<%= for {val, cnum} <- r do %>
<td phx-click="select_cell"
phx-value-x="<%= cnum %>"
phx-value-y="<%= rnum %>"
class="<%= if cnum == @selected_x && rnum == @selected_y do "selected" end %>">
<%= val %></td>
<% end %>
<td></td>
</tr>
<% end %>
</tbody>
</table>
I have about 150 columns and 10 000 rows.
The problem is that when I do the select_cell call, and update selected_x and selected_y the update takes a few seconds.
Is there a way to optimize this with live view, or should I move to JS?
Trending in Questions
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Hello,
I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind.
However, when I launch mix phx.server, I get an error...
New
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
Hello folks!
So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
I’m working on a small exercise involving update_in/3, and I came up with this solution:
data = %{
name: "Periodic Table",
category:...
New
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication):
toke...
New
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #ai
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
chrismccord
You should use temporary assigns for the rows and you can either use
phx-update="append"and append the two updated rows (the old row which is now unselected and the new selected row), or you can use a component for reach row, and do asend_updateto the old selected row, and newly selected row. Both options will send the minimal diff down and not require holding 10k rows in your server state.kuon
If I get this right, I should:
Is that the way to go?
chrismccord
You don’t need the pubsub step and instead of targeting the component, let the parent LV handle the event, then it performs the send_update to both the component children. The parent LV has the selected state, so it can use that to
send_updatethe selected component, then the handle_event params can contain the desired selected row, which you will use tosend_updatethe newly selected component. Make sense?kuon
Yes, it is working with
send_updatefrom the live view.I did create a component for each rows, but with large tables (>100 columns), even updating a single row takes a noticeable time.
Is it possible to nest components? Like having a component for the row that would just render
<tr class="...">and only handle the switch of class on the the row while using a for loop to render sub components? Would that just work?Also, I have a “tab” selector above my tables, and when I change tab, I need to re-render the whole table. Right now, live view is sending a “huge” diff with every rows when changing tabs. Is it possible to tell live view to just re-render the container and replace the whole container content in one operation?
50kudos
I have quite similar application, using
send_updatecan get hairy at some point (like jQuery approach, sometimes it needs other components updated too e.g. resetting [ui] state for the rest, and only update a component)I have a very big tree component (recursively rendered), so yes nested components is possible. However, the way out often is rethinking of state design. It’s quite tricky to get minimal diff payload for large DOM nodes.
I am moving towards more pagination, less DOM nodes is better. For the “tab”, you could possibly remodeling your assigns, moving assigns that make it marked as “changed” out, when switching tab 1 → tab 2 → tab 1 (this stays unchanged), but if you want always fresh data, I don’t think there is a way around other than reducing DOM nodes. (And I think
toStringon javascript side is not that performant .. something around Array.from that is slow)Also be aware of memory usage per process (per browser tab) too!
kuon
I tried to have a top component, like this:
This above component render a
tag with thousands of cells.Now, when I change the
@tablein the top component, instead of just having 1 single big difflike wrapper.innerHTML = "some big chunk of html"I have thousands and thousands of diffs which takes tens of seconds to be applied. (if I render the HTML normally without live view, rendering in the browser is instant)My tab selector could be regular links, but I want to keep the state between tab changes.
My use case is some sort of spreadsheet editor. I could use some JS lib, but I tested native HTML rendering, and everything is butter smooth with thousands of rows, browsers are really good at managing large pages and I thought I could leverage this with live view, but live view needs to have minimal diff.
kuon
I also tried nesting live views, but when the child live view is unmounted/remounted, there is also a huge diff which takes a very long time to be processed (much longer than just doing similar to
innerHTML = newdata).50kudos
My untested idea is that you could do something like what infinite twitter feed does, only render rows fit within screen viewport, not sure if it would be clunky or not. For example, 300 rows. The downside is native search on browser will suck.
That’s the only solution (pagination) I stick with, I gave up minimizing diff payload in other way since it’s going to have at least a bunch of one character keys (a lot of them alone without content is huge)
Or just give up view layer on server for those cells, just push_event with pure data and use whatever lib to render the cells on client.
50kudos
Also I guess your
sel: @selsit on every row (somewhere like<%= if @sel, do: "" %>), its change always mark the whole table (i.e. every row) as change and produce diff payload of every row even if@tabledata is unchanged.kuon
Well “smart partial client side rendering” is possible, but I want to avoid that because rendering the whole table works very well even with huge table.
And I don’t want to minimize diff size, what I’d like is to have a single large diff for the table when the table change, not a million small diffs for all element in the table.
As I said if I re-render the whole table, I’d like the container’s content to be swapped with the new content, in one single operation. I don’t want a million diff be applied, which is very slow.
So I am wondering if this is possible with live view.