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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks for the detailed response as always!</p>
<aside class="quote no-group" data-username="LostKobrakai" data-post="82" data-topic="34743">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/48/3072_2.png" class="avatar"> LostKobrakai:</div>
<blockquote>
<p>Yes the UI would by default reset. But that only matters for stuff that the server doesn’t know about. All the information that lives on the server should render the absolute same no matter which app server you hit.</p>
</blockquote>
</aside>
<p>If there are two servers for redundancy, A and B, and a client has an LV connection to server A. If server A goes down for whatever reason, the client can connect to server B. This will cause a state reset that would not be necessary if state was managed on the client, is my understanding. Is that right?</p>
<p>The examples regarding URLs and forms make sense for restoring state, but that’s effectively reusing the SPA stateless server paradigm by sending the state from the client.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="377975" 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/phoenix-liveview-vs-spa/34743/83">Post #82</a>
	                </div>
	            </div>
              <div id="likers-container-377975" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="377975"
                     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 #82"></div>
  </section>
</div>
    <div class="postbit" id="377977" data-post-id="377977">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="adamu" data-post="83" data-topic="34743">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/adamu/48/31482_2.png" class="avatar"> adamu:</div>
<blockquote>
<p>If there are two servers for redundancy, A and B, and a client has an LV connection to server A. If server A goes down for whatever reason, the client can connect to server B. This will cause a state reset that would not be necessary if state was managed on the client, is my understanding.</p>
</blockquote>
</aside>
<p>That’s true if the “state” once delivered to the client stays valid – again something you don’t really need LV for. Say you have a LV page constantly updating with some changes on the server. Dropping the connection doesn’t leave the client with valid or up to date state. Reconnection in that case does bring the client back to that. That “constant update” could be page content, but could also be interactive pieces like form validations (some of which also need the server like uniqueness). If you start from “my state lives on the client” then you’re expectedly going to be disappointed by LV.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="377977" 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/phoenix-liveview-vs-spa/34743/84">Post #83</a>
	                </div>
	            </div>
              <div id="likers-container-377977" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="377977"
                     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 #83"></div>
  </section>
</div>
    <div class="postbit" id="378010" data-post-id="378010">
  <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 no-group" data-username="LostKobrakai" data-post="82" data-topic="34743">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/48/3072_2.png" class="avatar"> LostKobrakai:</div>
<blockquote>
<p>But that only matters for stuff that the server doesn’t know about. All the information that lives on the server should render the absolute same no matter which app server you hit. That’s most of the value you get from LV – not needing to jump through hoops to bring stuff you need the server for anyways onto the client in a way it can be updated and react to user input.</p>
</blockquote>
</aside>
<p>This is not <em>wrong</em>, but I think this perspective misses the point.</p>
<p>What you are describing, rendering stateless pages using the URL, is essentially the HATEOAS approach that HTMX is championing. They are very clear about this: their approach is about extending HTML and hypermedia and that they are not competing with SPAs and React. I respect the restraint and I don’t think anything is wrong with their approach. It makes a lot of sense for some things. Web pages are cool too.</p>
<p>But for building <em>apps</em> that approach sucks. You cannot stuff all of the state of a page into the URL, nor can you use HATEOAS and links and so on to build rich interactive experiences. HTML is just not expressive enough. This has been known for a while, which is why React and similar frameworks <em>exist</em>.</p>
<p>What is special about LiveView is that it is actually more like React than HTMX. LiveView is like “React on the server” or “thin client React”. There are actually classes of problems for which this is an interesting and useful approach. Like, think of the AWS console: pretty much <em>all</em> of the state exists server-side. That sort of thing is naturally amenable to a thin client approach.</p>
<p>But if you want to take advantage of “thin client React” you need to keep state in the LiveView process. If you degrade your model back down to “render the LiveView statelessly”, what exactly is it that you’re doing that cannot be done with HTMX? All you have done is degrade a stateful framework into a stateless one!</p>
<p>I think the reality is that if you have a use-case where disconnects with the server will be frequent then LiveView is not a good fit. Though there is definitely more that could be done to keep a LiveView alive on the server and try to reconnect with it.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="378010" 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/phoenix-liveview-vs-spa/34743/85">Post #84</a>
	                </div>
	            </div>
              <div id="likers-container-378010" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="378010"
                     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 #84"></div>
  </section>
</div>
    <div class="postbit" id="378013" data-post-id="378013">
  <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 no-group" data-username="LostKobrakai" data-post="82" data-topic="34743">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/48/3072_2.png" class="avatar"> LostKobrakai:</div>
<blockquote>
<p>due to how morphdom works. It wholesale replaces dom nodes without ids and also removes all client side changes unless they’re made in a way for LV to recognise them. If LV would use different means of updating the DOM client side that complexity could be improved upon, but I doubt that’ll happen.</p>
</blockquote>
</aside>
<p>You know, I have actually been thinking about this one a lot. The morphdom/template-based diff approach the engine takes is directly upstream of what I think is LiveView’s biggest design flaw: poor composition. LiveComponents don’t compose, lifecycle hooks don’t compose, JS hooks don’t compose, etc. Keyed <code>:for</code> almost didn’t compose and the fact that it took Jose and Steffen (both of whom obviously know what they’re doing) something like 50 commits to make it work is evidence to me that the underlying engine is just designed wrong.</p>
<p>At this point I do think there is a path. I haven’t nailed it down <em>exactly</em> yet but I’m pretty sure if you do element-level diffs on the tree (as opposed to dynamic/static splitting the text), assign ids to components, and keep an <code>id =&gt; dom ref</code> mapping on the client you can do a React-style diff across the network.</p>
<p>The messiest bit is that React encodes the diffs into the tree in such a way that the childrens’ diffs can reference the parent. Like, the diff is computed during a time-sliced rendering pass and then during the commit pass, once the child is being diffed in the actual dom, the parent’s dom ref is already available. But it <em>wasn’t</em> available during rendering. This indicates that the diffs themselves actually <em>have</em> to be tree-shaped, which I found weird and unintuitive at first.</p>
<p>(It also means that deletes are handled by deleting the parent element in the DOM with no regard for its children, which is a funny hack that having a tree-shaped DOM allows for.)</p>
<p>So I <em>think</em> sending down tree-shaped element-level diffs rooted in a known component is enough to build a better diff engine. At some point I will sit down and try to implement it and we’ll find out <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>
<p>Another interesting note is that this would require a VDOM on the server, which seems reasonable to me as it would also make the diffs on the wire smaller. Though again the main benefit would be ditching the global keys and enabling proper composition.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="378013" 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/phoenix-liveview-vs-spa/34743/86">Post #85</a>
	                </div>
	            </div>
              <div id="likers-container-378013" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="378013"
                     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 #85"></div>
  </section>
</div>
    <div class="postbit" id="378057" data-post-id="378057">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="LostKobrakai" data-post="84" data-topic="34743">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/48/3072_2.png" class="avatar"> LostKobrakai:</div>
<blockquote>
<p>If you start from “my state lives on the client” then you’re expectedly going to be disappointed by LV.</p>
</blockquote>
</aside>
<p>I have to admit, the cause of this soul-searching about keeping state in memory on the server was watching this talk, specifically the section between 27:48 ~ 30:10. Quoting the last sentence from that section:</p>
<blockquote>
<p>We’re not trying to keep hold of in-memory state. Trying to build statefull processing systems, it is complicated to do, it is very difficult to scale. Just don’t do it.</p>
</blockquote>
<div class="youtube-onebox lazy-video-container" data-video-id="8ybqsEg2HYs" data-video-title="Keynote: You Keep Using That Word - Sam Newman | MQ Summit 2025" data-video-start-time="1668s" data-provider-name="youtube">
  <a href="https://www.youtube.com/watch?v=8ybqsEg2HYs&amp;t=1668s" target="_blank" class="video-thumbnail" rel="noopener nofollow ugc">
    <img class="youtube-thumbnail" src="https://img.youtube.com/vi/8ybqsEg2HYs/maxresdefault.jpg" title="Keynote: You Keep Using That Word - Sam Newman | MQ Summit 2025" width="690" height="388">
  </a>
</div>
 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="378057" 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/phoenix-liveview-vs-spa/34743/87">Post #86</a>
	                </div>
	            </div>
              <div id="likers-container-378057" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="378057"
                     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 #86"></div>
  </section>
</div>
    <div class="postbit" id="378064" data-post-id="378064">
  <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 no-group" data-username="garrison" data-post="86" data-topic="34743">
<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>the fact that it took Jose and Steffen (both of whom obviously know what they’re doing) something like 50 commits to make it work is evidence to me that the underlying engine is just designed wrong.</p>
</blockquote>
</aside>
<p>I am not a big fan of this type of argument because:</p>
<ol>
<li>it is a partial “appeal to authority” as it implies Steffen and I do not make mistakes or get things wrong</li>
<li>it implies the correct design for `:for` components is something immediately obvious that we’d have stumbled upon. Maybe it took long not because of the engine, but because we wanted to design `:for` correctly!</li>
</ol>
<p>There is also a matter of optimizations. The engine may be simple conceptually, what makes it complex is all of the optimizations that are put in place. Like a language that looks simple on surface and is then sitting on layers and decades of optimization, which then makes changing the language harder.</p>
<p>To be clear, I am not saying the engine is right or wrong, but I am saying some of the arguments you are giving are not indication of wrong design. <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="378064" 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/phoenix-liveview-vs-spa/34743/88">Post #87</a>
	                </div>
	            </div>
              <div id="likers-container-378064" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="378064"
                     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 #87"></div>
  </section>
</div>
    <div class="postbit" id="378065" data-post-id="378065">
  <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 no-group" data-username="garrison" data-post="86" data-topic="34743">
<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>So I <em>think</em> sending down tree-shaped element-level diffs rooted in a known component is enough to build a better diff engine. At some point I will sit down and try to implement it and we’ll find out <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>
</blockquote>
</aside>
<p>For what is worth, there are libraries that do this on the client, similar to morphdom but then it uses the node’s parent and children nodes to identify if it changed or not, reducing the amount of churn.</p>
<p>My critique about this approach is that you are relying on something completely out of your control to keep the client state and it will break in very subtle and unexpected ways when you do a change elsewhere.</p>
<p>I don’t think moving the tree to the server fundamentally addresses this problem either. As the problem is the same: if you have two trees, which nodes are the same and which ones are not? Because they are not identical trees where nodes simply change, you can have children nodes being added anywhere at any moment, or being moved around in terms of nesting.</p>
<p>But if you folks want to play with keeping more DOM elements around and reduce morphdom trashing, one option would be to try JS libraries like above, but you can also try to get some help server side, for example:</p>
<ol>
<li>Change HEEx to add a data-heex-id to each element, which is generated at compile time</li>
<li>Change morphdom to compare the children of a given node using the data-heex-id to detect lateral movements (i.e. a child moving up or down its siblings)</li>
</ol>
<p>The ID search goes through the whole tree, but this is to help detect sibling movements (nodes added or moved around to a given parent). But once again, it won’t be perfect, and people may accidentally rely on this.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="378065" 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/phoenix-liveview-vs-spa/34743/89">Post #88</a>
	                </div>
	            </div>
              <div id="likers-container-378065" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="378065"
                     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 #88"></div>
  </section>
</div>
    <div class="postbit" id="378070" data-post-id="378070">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think the context matters here. Yes this advice seems to be sound, but the systems being described here are likely ones, which want to scale to x/sec messages, where x is a really large number. You don’t want to update a LV that often. With a network in between even targeting 30fps is unlikely reasonable for real world application. On the other side events are driven by human interaction. So the per LV amount of events should be fine. Now you could still have thousands upon thousands of concurrent users, but not everyone has. The routing problem described only exists for long polling, but with websockets responses automatically go back to the correct node and you generally want users on a websocket connection.</p>
<p>Don’t get me wrong. You can build your frontend to be a thick client and have the server be stateless and it’ll be fine. But that means you need to bring all the data to that thick client. LV seriously shortcuts the work needed to get the rendered information to the client without needing all the boilerplate to ship the underlying data to the client. I also do not think LV is like a magical solution fit for every problem. It surely does have tradeoffs. I haven’t had enough time with HTMX, but it feels like it would be way to easy to have part A of a page updated, but miss updating part B, which also depends on information changed for part A.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="378070" 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/phoenix-liveview-vs-spa/34743/90">Post #89</a>
	                </div>
	            </div>
              <div id="likers-container-378070" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="378070"
                     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 #89"></div>
  </section>
</div>
    <div class="postbit" id="378104" data-post-id="378104">
  <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">
								<p>Oh I wasn’t trying to appeal to authority or anything. What I meant was that I know you guys obviously understand the engine very well so the fact that this change was a lot of work indicates to me that you were fighting an “uphill battle”. I’m not saying this is an argument that stands <em>on its own</em>, though; it was just added color in context.</p>
<p>I had actually made a similar point <em>before</em> you guys fixed the <code>:for</code> composition issue, but at the time I had not yet figured out how to do it “the right way”. It’s hard because the React engine does not have these problems but the React engine also heavily abuses DOM refs in the tree in a way that LV cannot because it’s on the wrong side of a network.</p>
<p>I <em>think</em> I now see the way to do this, but I’m not saying it’s easy! Designing an engine that handles composition better will likely be <em>more</em> work, all I meant is that <em>once that engine exists</em> getting rid of global <code>id</code>s should be trivial whereas with LV’s engine it was clearly not easy to retrofit in the case of keyed <code>:for</code>.</p>
<p>I know you put so much effort into redesigning keyed <code>:for</code> because you cared about getting it right. I cared about it too, which is why I had raised the concern with you at the time. What I appreciate most about the Elixir community is that there is a culture here of caring about such things, and that is the spirit in which I’m posting <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>
<p>I will give some more consideration to the engine design, as I am pretty sure there is a better design lurking. This doesn’t mean LV’s existing engine is somehow “bad” btw, I think it’s just a natural progression. LV is more powerful now than it was perhaps intended to be initially.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="378104" 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/phoenix-liveview-vs-spa/34743/91">Post #90</a>
	                </div>
	            </div>
              <div id="likers-container-378104" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="378104"
                     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 #90"></div>
  </section>
</div>
    <div class="postbit" id="378166" data-post-id="378166">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="garrison" data-post="91" data-topic="34743">
<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></blockquote>
</aside>
<p>Please check <a href="https://data-star.dev" rel="noopener nofollow ugc">data-star.dev</a> when you find time. They have modified idiomorph and claim they have the fastest morhping and signals implementation. Its worth a look.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="378166" 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/phoenix-liveview-vs-spa/34743/92">Post #91</a>
	                </div>
	            </div>
              <div id="likers-container-378166" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="378166"
                     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>