<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="367872" data-post-id="367872">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Jskalc" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Jskalc/120/35876_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Jskalc
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thank you Steffen! <img src="https://forum.elixirforum.com/images/emoji/apple/heart.png?v=15" title=":heart:" class="emoji" alt=":heart:" loading="lazy" width="20" height="20"></p>
<p>It’s a huuge improvement! Now developers can get these huge diff size gains without much effort.</p>
<p>I was looking into this, and there’s these two possible improvements:</p>
<ul>
<li>when :key is present, payload still increases linearly with length of the collection due to always sending a full list of LiveComponent ids. I think it helps when reordering, but is it necessary when order doesn’t change? <img src="https://forum.elixirforum.com/images/emoji/apple/thinking.png?v=15" title=":thinking:" class="emoji" alt=":thinking:" loading="lazy" width="20" height="20"></li>
</ul>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/7/5/7518507dddf21539ed8cc400cd2be868d26fcdbe.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/7518507dddf21539ed8cc400cd2be868d26fcdbe" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/7/5/7518507dddf21539ed8cc400cd2be868d26fcdbe_2_517x309.jpeg" alt="image" data-base62-sha1="gHRXmqKSR2AT6mq7tqM67K2bnHM" width="517" height="309" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/7/5/7518507dddf21539ed8cc400cd2be868d26fcdbe_2_517x309.jpeg, https://forum.elixirforum.com/uploads/default/optimized/3X/7/5/7518507dddf21539ed8cc400cd2be868d26fcdbe_2_775x463.jpeg 1.5x, https://forum.elixirforum.com/uploads/default/optimized/3X/7/5/7518507dddf21539ed8cc400cd2be868d26fcdbe_2_1034x618.jpeg 2x" data-dominant-color="2B2C2C"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1200×717 44.1 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<ul>
<li>memory overhead is much higher than I thought it would be. I might be measuring it in a wrong way, just I have a feeling LiveComponents were not really optimized for memory overhead.</li>
</ul>
<p>Without keys:</p>
<div class="md-table">
<table>
<thead>
<tr>
<th>Array length</th>
<th>Heap size</th>
<th>Payload size</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>987</td>
<td>78 (empty)</td>
</tr>
<tr>
<td>1</td>
<td>987</td>
<td>112</td>
</tr>
<tr>
<td>10</td>
<td>987</td>
<td>238</td>
</tr>
<tr>
<td>100</td>
<td>2586</td>
<td>1497</td>
</tr>
<tr>
<td>1000</td>
<td>17731</td>
<td>14098</td>
</tr>
</tbody>
</table>
</div><p>With keys:</p>
<div class="md-table">
<table>
<thead>
<tr>
<th>Array length</th>
<th>Heap size</th>
<th>Payload size</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>987</td>
<td>78 (empty)</td>
</tr>
<tr>
<td>1</td>
<td>987</td>
<td>138</td>
</tr>
<tr>
<td>10</td>
<td>4185</td>
<td>175</td>
</tr>
<tr>
<td>100</td>
<td>28690</td>
<td>625</td>
</tr>
<tr>
<td>1000</td>
<td>121536</td>
<td>6029</td>
</tr>
</tbody>
</table>
</div><p>Both these issues are less important when using more complex items, since I assume memory overhead for LiveComponent record is constant (didn’t measure it though). But now let’s remember LiveComponent usage will be much much easier thanks to :key syntax, so optimizing it might be more important? Still - can’t shake that feeling it could be done almost without memory overhead. Like, compare previous assign to the current one without using LiveComponents at all. I’ve tried doing it by myself and failed, engine code is not the easiest one to grasp <img src="https://forum.elixirforum.com/images/emoji/apple/face_with_peeking_eye.png?v=15" title=":face_with_peeking_eye:" class="emoji" alt=":face_with_peeking_eye:" loading="lazy" width="20" height="20"></p>
<p>This is a simple livebook I’ve used:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Mix.install([
  {:phoenix_playground, "~&gt; 0.1.6"},
  {:phoenix_live_view, github: "phoenixframework/phoenix_live_view", branch: "main", override: true},
])

defmodule DemoLive do
  use Phoenix.LiveView

  require Logger

  @list_size 1000

  def mount(_params, _session, socket) do
    list = Enum.map(1..@list_size, fn i -&gt; %{index: i, value: random_value()} end)
    report_memory_usage()
    {:ok, assign(socket, list: list)}
  end

  def render(assigns) do
    ~H"""
    &lt;button phx-click="randomize"&gt;Randomize&lt;/button&gt;
    &lt;div :for={item &lt;- @list} :key={item.index}&gt;
      {item.value} {item.value + 1} {item.value + 2}
    &lt;/div&gt;
    """
  end

  def handle_event("randomize", _params, socket) do
    index = Enum.random(1..@list_size)
    new_list = put_in(socket.assigns.list, [Access.at(index - 1), :value], random_value())
    report_memory_usage()
    {:noreply, assign(socket, list: new_list)}
  end

  defp random_value() do
    Enum.random([1, 2, 3])
  end

  defp report_memory_usage() do
    :erlang.garbage_collect()
    Logger.info("Heap size: #{Process.info(self())[:total_heap_size]}")
  end
end

PhoenixPlayground.start(live: DemoLive)
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367872" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/possible-payload-size-improvement-to-heex-list-comprehensions/64986/42">Post #41</a>
	                </div>
	            </div>
              <div id="likers-container-367872" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367872"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #41"></div>
  </section>
</div>
    <div class="postbit" id="367887" data-post-id="367887">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="steffend" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/steffend/120/20548_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  steffend
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Phoenix Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Jskalc" data-post="42" data-topic="64986">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jskalc/48/35876_2.png" class="avatar"> Jskalc:</div>
<blockquote>
<p>I think it helps when reordering, but is it necessary when order doesn’t change? <img src="https://forum.elixirforum.com/images/emoji/apple/thinking.png?v=15" title=":thinking:" class="emoji" alt=":thinking:" loading="lazy" width="20" height="20"></p>
</blockquote>
</aside>
<p>It’s necessary right now because that’s how LiveComponent rendering works and it’s really just LiveComponents under the hood, no further optimizations apart from some change-tracking trickery.</p>
<aside class="quote no-group" data-username="Jskalc" data-post="42" data-topic="64986">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jskalc/48/35876_2.png" class="avatar"> Jskalc:</div>
<blockquote>
<p>memory overhead is much higher than I thought it would be. I might be measuring it in a wrong way, just I have a feeling LiveComponents were not really optimized for memory overhead.</p>
</blockquote>
</aside>
<p>Thank you for experimenting with this! Each LiveComponent comes with some overhead for its state (socket, lifecycle), so yeah, it’s definitely not perfect for this use case.</p>
<aside class="quote no-group" data-username="Jskalc" data-post="42" data-topic="64986">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jskalc/48/35876_2.png" class="avatar"> Jskalc:</div>
<blockquote>
<p>But now let’s remember LiveComponent usage will be much much easier thanks to :key syntax, so optimizing it might be more important? Still - can’t shake that feeling it could be done almost without memory overhead. Like, compare previous assign to the current one without using LiveComponents at all. I’ve tried doing it by myself and failed, engine code is not the easiest one to grasp <img src="https://forum.elixirforum.com/images/emoji/apple/face_with_peeking_eye.png?v=15" title=":face_with_peeking_eye:" class="emoji" alt=":face_with_peeking_eye:" loading="lazy" width="20" height="20"></p>
</blockquote>
</aside>
<p>I agree that it would be nice to optimize this further, but that would require a whole new diffing algorithm + diff format for keyed comprehensions, which is not something I was able to wrap my head around yet.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367887" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/possible-payload-size-improvement-to-heex-list-comprehensions/64986/43">Post #42</a>
	                </div>
	            </div>
              <div id="likers-container-367887" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367887"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #42"></div>
  </section>
</div>
    <div class="postbit" id="367928" data-post-id="367928">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-Phoenix-Core-Team" data-username="steffend" data-post="43" data-topic="64986">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/steffend/48/20548_2.png" class="avatar"> steffend:</div>
<blockquote>
<p>Thank you for experimenting with this! Each LiveComponent comes with some overhead for its state (socket, lifecycle), so yeah, it’s definitely not perfect for this use case.</p>
</blockquote>
</aside>
<p>I am sure this can be optimised in future releases, so I am not very worried about it. Optimising it would mean refactoring the Diff module, which is one of the most complex parts of the codebase, so ti should be a win-win.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367928" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/possible-payload-size-improvement-to-heex-list-comprehensions/64986/44">Post #43</a>
	                </div>
	            </div>
              <div id="likers-container-367928" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367928"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #43"></div>
  </section>
</div>
    <div class="postbit" id="367956" data-post-id="367956">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="44" data-topic="64986">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>Optimising it would mean refactoring the Diff module, which is one of the most complex parts of the codebase</p>
</blockquote>
</aside>
<p>If this code is going to be refactored heavily at some point I would like to quickly throw my hat in the ring and argue that LiveComponents (or similar) should be diffed with <em>local</em> keys rather than global keys, because (as I showed a couple posts up) global keys do not compose properly and cause problems. I have even managed to run into collisions a couple times in my <em>own apps</em>, where I 100% control the keys, and it can only get worse from there.</p>
<p>I have read <em>some</em> of the LV code, but I don’t have near the understanding needed to know how hard this would be. IIRC you are the original author of the LiveComponent feature, so maybe you can shed some light there. (Though TBH I don’t usually remember how my own code works after even a few months lol)</p>
<p>I’m not sure how you would handle this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def render(assigns) do
  ~H"""
  &lt;div&gt;
    &lt;div&gt;
      &lt;.user :for={user &lt;- @some_users} :key={user.id} /&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;.item :for={item &lt;- @items} :key={item.id} /&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  """
end
</code></pre>
<p>If there are multiple comprehensions in a component, you can’t get away with having one node in the tree per <em>component</em>. The tree structure has to match the <em>dom node</em> structure because only a node is guaranteed to have a single list of children.</p>
<p>Given that HEEX splits components into statics/dynamics, I have a sneaking suspicion accounting is all done at the component level, although there are probably structures to deal with comprehensions and conditionals, right? Maybe those could be modified to do the job, I’m not sure.</p>
<p>Conditionals are easy as long as they return the same number of children (<code>nil</code> is a valid child node). Comprehensions are what necessitate the <code>:key</code>s to keep the diff fast. I <em>think</em> React mounts fibers for <em>every</em> node (not just components) because I don’t see how else they would deal with this, but strangely I have been unable to find any mention of that fact anywhere. I’ll probably have to look at the code to know for sure.</p>
<p>But yeah, I worry this would turn into “rewrite the entire LiveView engine”. Which would probably be worth it TBH, but that’s a lot easier to say when you’re not the one <em>doing</em> it… <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367956" data-batch-url="/posts/batch_likers">
                        7
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/possible-payload-size-improvement-to-heex-list-comprehensions/64986/45">Post #44</a>
	                </div>
	            </div>
              <div id="likers-container-367956" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367956"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #44"></div>
  </section>
</div>
    <div class="postbit" id="367969" data-post-id="367969">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think this is an interesting idea that I would explore right now.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="367969" data-batch-url="/posts/batch_likers">
                        12
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/possible-payload-size-improvement-to-heex-list-comprehensions/64986/46">Post #45</a>
	                </div>
	            </div>
              <div id="likers-container-367969" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="367969"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #45"></div>
  </section>
</div>
    <div class="postbit" id="368286" data-post-id="368286">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="steffend" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/steffend/120/20548_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  steffend
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Phoenix Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>There’s a new branch for you to try out: <a href="https://github.com/phoenixframework/phoenix_live_view/pull/3865" rel="noopener nofollow ugc">https://github.com/phoenixframework/phoenix_live_view/pull/3865</a></p>
<aside class="quote no-group" data-username="Jskalc" data-post="42" data-topic="64986">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jskalc/48/35876_2.png" class="avatar"> Jskalc:</div>
<blockquote>
<p>I think it helps when reordering, but is it necessary when order doesn’t change? <img src="https://forum.elixirforum.com/images/emoji/apple/thinking.png?v=15" title=":thinking:" class="emoji" alt=":thinking:" loading="lazy" width="20" height="20"></p>
</blockquote>
</aside>
<p>The new code only sends a position when it changed or moved.</p>
<aside class="quote no-group" data-username="garrison" data-post="37" data-topic="64986">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>I saw this is based on LiveComponents internally, so I would assume the <code>:key</code> has to be a global id. But I don’t see that mentioned in the docs anywhere. Is that the case?</p>
</blockquote>
</aside>
<p>Also, the new branch does not use live components any more, so the keys are all local.</p>
<p>This also adjusts all other comprehensions to be implicitly keyed by their index, so nested change tracking also applies whenever you omit the key, which is useful for things like slots.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="368286" data-batch-url="/posts/batch_likers">
                        14
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/possible-payload-size-improvement-to-heex-list-comprehensions/64986/48">Post #47</a>
	                </div>
	            </div>
              <div id="likers-container-368286" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="368286"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #47"></div>
  </section>
</div>
    <div class="postbit" id="368288" data-post-id="368288">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Schultzer" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Schultzer/120/4339_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Schultzer
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Amazing work, great to see this!</p>
<p><a class="mention" href="/u/garrison" rel="nofollow">@garrison</a> Much appreciated your ability to communicate in a way that people could see why and a clear path for implementing this. Something I know a lot of us has tried to advocate for but failed to get over the line!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="368288" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/possible-payload-size-improvement-to-heex-list-comprehensions/64986/49">Post #48</a>
	                </div>
	            </div>
              <div id="likers-container-368288" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="368288"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #48"></div>
  </section>
</div>
    <div class="postbit" id="368292" data-post-id="368292">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The need was always clear but we just never knew how. <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> The main insight though was to indeed use the position in the tree as a key but even then this is the third or fourth try in making this work in the last 5 days, so we needed a few more breakthroughs!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="368292" data-batch-url="/posts/batch_likers">
                        6
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/possible-payload-size-improvement-to-heex-list-comprehensions/64986/50">Post #49</a>
	                </div>
	            </div>
              <div id="likers-container-368292" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="368292"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #49"></div>
  </section>
</div>
    <div class="postbit" id="368296" data-post-id="368296">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Schultzer" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Schultzer/120/4339_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Schultzer
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I don’t doubt it, there is always unknown unknowns.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="368296" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/possible-payload-size-improvement-to-heex-list-comprehensions/64986/51">Post #50</a>
	                </div>
	            </div>
              <div id="likers-container-368296" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="368296"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #50"></div>
  </section>
</div>
    <div class="postbit" id="368298" data-post-id="368298">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Jskalc" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Jskalc/120/35876_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Jskalc
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This is amazing, thank you <a class="mention" href="/u/steffend" rel="nofollow">@steffend</a> !</p>
<p>I don’t have much time now to re-run all the tests, but for 100 &amp; 1000 items and keys enabled:</p>
<div class="md-table">
<table>
<thead>
<tr>
<th>Array length</th>
<th>Heap size</th>
<th>Payload size</th>
</tr>
</thead>
<tbody>
<tr>
<td>100</td>
<td>6772</td>
<td>138</td>
</tr>
<tr>
<td>1000</td>
<td>46422</td>
<td>138</td>
</tr>
</tbody>
</table>
</div><p>Payload size is constant, unless we move items around or insert in the middle. Worst case is prepending without explicit keys, but it’s much better anyway. There seem to be some overhead on memory, I assume you keep around previous keys (didn’t had time to look into the implementation).</p>
<p>Super excited for this <img src="https://forum.elixirforum.com/images/emoji/apple/heart_eyes.png?v=15" title=":heart_eyes:" class="emoji" alt=":heart_eyes:" loading="lazy" width="20" height="20"> I think it might be one of the biggest performance optimizations in LiveView!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="368298" data-batch-url="/posts/batch_likers">
                        7
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/possible-payload-size-improvement-to-heex-list-comprehensions/64986/52">Post #51</a>
	                </div>
	            </div>
              <div id="likers-container-368298" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="368298"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>