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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Why not some type of VDOM solution? I imagine it would be faster than comparing HTML strings, but tbh I have no clue what the performance difference would be.</p>
<p>And what’s the problem with polluting the DOM with custom attributes?</p>
<p>(I am a bit out of my depth here, so these are honest questions!)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="96156" 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/54-elixirconf-us-2018-closing-keynote-chris-mccord/16445/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-96156" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="96156"
                     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 #21"></div>
  </section>
</div>
    <div class="postbit" id="96157" data-post-id="96157">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I really hope <a class="mention" href="/u/chrismccord" rel="nofollow">@chrismccord</a> works with you on LiveView. You’ve definitely pioneered and popularized this entire concept within this community.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="96157" data-batch-url="/posts/batch_likers">
                        20
                      </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/54-elixirconf-us-2018-closing-keynote-chris-mccord/16445/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-96157" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="96157"
                     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 #22"></div>
  </section>
</div>
    <div class="postbit" id="96159" data-post-id="96159">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="hilko" data-post="22" data-topic="16445">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/c57346/48.png" class="avatar"> hilko:</div>
<blockquote>
<p>Why not some type of VDOM solution?</p>
</blockquote>
</aside>
<p>Morphdom can patch a string representing a DOM into an existing DOM as fast as a VDOM solution (look at their github page here, where they explain how it’s possible: <a href="https://github.com/patrick-steele-idem/morphdom" class="inline-onebox" rel="noopener nofollow ugc">GitHub - patrick-steele-idem/morphdom: Fast and lightweight DOM diffing/patching (no virtual DOM needed) · GitHub</a>). Yes, it has to parse the string into a DOM and diff both DOM trees, but if you’re sending a VDOM from the server you’re not actually sending a JS object representing a VDOM. You’re sending a string representation of a VDOM, which has to be parsed into a VDOM in a way that’s probably slower than the browser parsing a string into a real DOM (this is the thing at which browsers are faster).</p>
<aside class="quote no-group" data-username="hilko" data-post="22" data-topic="16445">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/c57346/48.png" class="avatar"> hilko:</div>
<blockquote>
<p>I imagine it would be faster than comparing HTML strings, but tbh I have no clue what the performance difference would be.</p>
</blockquote>
</aside>
<p>As I said above, you’re not comparing HTML strings. You’re parsing the HTML into a DOM and comparing DOMs. Comparing the DOMs is not necessarily slower than using a VDOM.</p>
<aside class="quote no-group" data-username="hilko" data-post="22" data-topic="16445">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/c57346/48.png" class="avatar"> hilko:</div>
<blockquote>
<p>And what’s the problem with polluting the DOM with custom attributes?</p>
</blockquote>
</aside>
<p>It’s not that much of a problem, honestly… It’s just something I’d like to avoid if it was I implementing a solution. There was a time when Drab used to pollute your webpage with custom <code>&lt;span&gt;</code> elements, and that would cause some real trouble, but adding attributes is probably very safe and won’t cause problems.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="96159" 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/54-elixirconf-us-2018-closing-keynote-chris-mccord/16445/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-96159" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="96159"
                     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 #23"></div>
  </section>
</div>
    <div class="postbit" id="96160" data-post-id="96160">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Interesting! Sending HTML strings does strike me as a cleaner approach, all else being equal. It’s probably easier to test/debug/extend than any VDOM-type solution that starts on the server-side. Will definitely look into morphdom!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="96160" 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/54-elixirconf-us-2018-closing-keynote-chris-mccord/16445/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-96160" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="96160"
                     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 #24"></div>
  </section>
</div>
    <div class="postbit" id="96162" data-post-id="96162">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I also feel I must explain the rationale between my solution above (the one which sends only a list of strings into the browser). Having a VDOM computed on the server allows you to send minimal HTML DOM diffs, which the Javascript in the browser can apply to the DOM.</p>
<p>Browsers need the DOM because that’s important for interactivity and to actually render the HTML into pixels on your monitor. But the server doesn’t care about the DOM at all. The BEAM (and by extension Erlang and Elixir) is very efficient at sending bytes through a socket. Dealing with nested structures with backreferences like a DOM is definitely not something for which it is optimized. The main reason why Phoenix templates are so fast is that they do the least amount of work possible besides sending bytes through a socket (see here, for example: <a href="https://www.bignerdranch.com/blog/elixir-and-io-lists-part-2-io-lists-in-phoenix/" rel="noopener nofollow ugc">https://www.bignerdranch.com/blog/elixir-and-io-lists-part-2-io-lists-in-phoenix/</a>).</p>
<p>My solution (which <a class="mention" href="/u/chrismccord" rel="nofollow">@chrismccord</a> and <a class="mention" href="/u/josevalim" rel="nofollow">@josevalim</a> probably had in mind) intelligently divides work between the client and the server:</p>
<ol>
<li>The server cares only about pushing bytes around (because there isn’t a GUI to render those bytes). In my solution the server only deals with bytes.</li>
<li>Data transfered through the network is minimized because only the parts of the template that might change are sent.</li>
<li>The browser cares about a DOM, and is highly optimized to process and render a DOM, so all the DOM work is done on the browser.</li>
</ol> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="96162" 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/54-elixirconf-us-2018-closing-keynote-chris-mccord/16445/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-96162" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="96162"
                     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 #25"></div>
  </section>
</div>
    <div class="postbit" id="96165" data-post-id="96165">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>That all makes perfect sense. I also imagine that your solution is much easier to implement, as it would require <em>additional</em> client-side code instead of significant changes to server-side rendering.</p>
<p>Honestly, the only reason I dislike this whole LiveView/Drab-like approach is that I just recently converted a ‘regular’ Phoenix app, views and templates, to an JSON API-based approach with the usual Rube Goldberg client-side React implementation ;-). I’d much rather have stuck with Phoenix’ server-side rendering…</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="96165" 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/54-elixirconf-us-2018-closing-keynote-chris-mccord/16445/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-96165" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="96165"
                     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 #26"></div>
  </section>
</div>
    <div class="postbit" id="96166" data-post-id="96166">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>You can optimize data transfer even further at the cost of more memory and CPU cycles on both the server and the client by keeping the dynamic list of strings in memory. When you generate a new dynamic list of strings, you compare the new list and the old one. If strings are the same, you can just send a placeholder instead of the string (<code>null</code>, the integre <code>0</code>, etc). If you have long strings, this saves some space (a lot of space in some cases, even!).</p>
<p>Then, because you’re also keeping the dynamic list of strings in memory on the client, you can reconstruct the placeholders.</p>
<p>At which step you’re trading CPU and memory for data transfer. Depending on your solution, this might be the wrong choice. For example, while the overhead of keeping part of a webpage in memory is low on the client, if you have millions of users, you now have to keep millions of dynamic lists in memory, which might kill your servers… So it’s not a decision to make lightly.</p>
<p>Trading CPU usage for Network transfers is usually the right choice (the network is very slow), but it might transform an IO bound task (at which Elixir excels) into a CPU-bound task (at which Elixir does not excel)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="96166" 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/54-elixirconf-us-2018-closing-keynote-chris-mccord/16445/28">Post #27</a>
	                </div>
	            </div>
              <div id="likers-container-96166" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="96166"
                     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 #27"></div>
  </section>
</div>
    <div class="postbit" id="96167" data-post-id="96167">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="hilko" data-post="27" data-topic="16445">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/h/c57346/48.png" class="avatar"> hilko:</div>
<blockquote>
<p>I also imagine that your solution is much easier to implement, as it would require <em>additional</em> client-side code instead of significant changes to server-side rendering.</p>
</blockquote>
</aside>
<p>I don’t think of moving code from the server to the client as “easier to implement” xD The complexity is still there, (someone, maybe you, will have to maintain and debug it); you’re just moving complexity around. In this case, you’re building on top of the <code>morphdom</code> JS package, which has some complexity on its own.</p>
<p>The advantages of moving complexity around are that now you’re spending CPU cycles on the client instead of the server and you’re playing on the browser and the server’s strengths: the server dumps dumb bytes into a socket and the client builds and handles a “smart” DOM</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="96167" 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/54-elixirconf-us-2018-closing-keynote-chris-mccord/16445/29">Post #28</a>
	                </div>
	            </div>
              <div id="likers-container-96167" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="96167"
                     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 #28"></div>
  </section>
</div>
    <div class="postbit" id="96171" data-post-id="96171">
  <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="tmbb" data-post="14" data-topic="16445">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/t/77aa72/48.png" class="avatar"> tmbb:</div>
<blockquote>
<p>cross-compile the EEx template into a javscript function which takes the <em>dynamic substrigs</em> as arguments (not the arguments to the template function!). For example:</p>
</blockquote>
</aside>
<p>This is the approach I suggested but it doesn’t work with nesting (for example, <code>form_for</code>). So when using LiveView someone would need to reduce the amount of nesting that happens in templates (it is doable though). So different tools will make different trade-offs here and that’s totally fine IMO. Hard to say which one is the best without benchmarking and looking at example applications.</p>
<aside class="quote no-group" data-username="blatyo" data-post="15" data-topic="16445">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/blatyo/48/4554_2.png" class="avatar"> blatyo:</div>
<blockquote>
<p>I’m very excited about this. I’m interested in building integration with this for <a href="https://www.conduitframework.com/" rel="nofollow">conduit </a>.</p>
</blockquote>
</aside>
<p>Me too! The repo is out, although very early on: <a href="https://github.com/elixir-telemetry/telemetry/" class="inline-onebox" rel="nofollow">GitHub - beam-telemetry/telemetry: Dynamic dispatching library for metrics and instrumentations. · GitHub</a> - We are considering already integrating it with Ecto 3.0 though.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="96171" 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/54-elixirconf-us-2018-closing-keynote-chris-mccord/16445/30">Post #29</a>
	                </div>
	            </div>
              <div id="likers-container-96171" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="96171"
                     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 #29"></div>
  </section>
</div>
    <div class="postbit" id="96172" data-post-id="96172">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thank You for your amazing tool, cannot wait to see what will come next <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="96172" data-batch-url="/posts/batch_likers">
                        4
                      </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/54-elixirconf-us-2018-closing-keynote-chris-mccord/16445/31">Post #30</a>
	                </div>
	            </div>
              <div id="likers-container-96172" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="96172"
                     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 #30"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/16445/load_more?page=4">Load more posts (56 remaining)</a>
</div></template></turbo-stream>