<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="356450" data-post-id="356450">
  <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>There has already been a lot of good information in this thread, I want to give my two cents from building DBVisor, which is a highly complex dashboard, where I’m breaking the old myth about too many elements on a page or table <a href="https://stackoverflow.com/questions/5240024/how-can-i-optimise-this-html-to-render-faster-in-the-browser" rel="noopener nofollow ugc">https://stackoverflow.com/questions/5240024/how-can-i-optimise-this-html-to-render-faster-in-the-browser</a></p>
<p>First of all, there is no free lunch when it comes to Phoenix and LiveView. I’ve done multiple iteration where I would do mostly custom diffing client side to increase rendering and avoid morphdom, but in my latest iteration I’m mainly using streams, function components in one LV, I never use LiveComponents.</p>
<p>I pay special attention to my html construction since that can have great importance an example is this issue <a href="https://github.com/patrick-steele-idem/morphdom/issues/228" class="inline-onebox" rel="noopener nofollow ugc">Morphing page with a lot (1000 or so) FORM tags is slow · Issue #228 · patrick-steele-idem/morphdom · GitHub</a> which shows that having to many form elements slows the page.</p>
<p>You also want to pay attention to CSS, layout shift, painting etc. lighthouse will give you a decent report, but there is nothing like production.</p>
<p>With everything in software, performance comes by reducing the amount of work. So if you can cut down on unnecessary elements, classes, styles, data, chatter and code. Then you can see gains.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="356450" 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/liveview-performance-problems-morphdom-taking-up-to-1500ms-to-patch-updates/69408/32">Post #31</a>
	                </div>
	            </div>
              <div id="likers-container-356450" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="356450"
                     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 #31"></div>
  </section>
</div>
    <div class="postbit" id="356454" data-post-id="356454">
  <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="31" data-topic="69408">
<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>I’m a bit afraid of the fact that to render useful content on initial page load they seem to depend on server-side rendering</p>
</blockquote>
</aside>
<p>You probably don’t need your form rendered in the initial page load anyway (and even less if your app requires authentication anyway), so is the initial page load a concern if you use <code>live_vue</code> for the forms?</p>
<aside class="quote no-group" data-username="tozz" data-post="30" data-topic="69408">
<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/a8b319/48.png" class="avatar"> tozz:</div>
<blockquote>
<p>I’ve been running into similar problems, my biggest problem is that you can’t nest forms according to the spec so you’re stuck between not being able to use the nice benefits of the Ecto/Phoenix integration or building custom javascript hooks trying to merge multiple forms (and same thing on the backend side with multiple changesets).</p>
</blockquote>
</aside>
<p>After reading <a class="mention" href="/u/tmjoen" rel="nofollow">@tmjoen</a>’s suggestion, I was thinking if something like that could be part of LiveView. Basically a way to say that a form is embedded in another form, and we could automatically stitch it back together. In pseudo-code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">&lt;form id="parent" phx-embeddable&gt;
  &lt;input name="posts" /&gt;
  ...
  &lt;!-- there may be a better tag --&gt;
&lt;/form&gt;

&lt;form phx-embed-at="#parent" phx-embed-as="posts[comments][0]"&gt;
  ...
&lt;/form&gt;
</code></pre>
<p>Then LiveView would put everything under the comments at “posts[comments][0]” for you, so you don’t have to do anything. Can you please tell us about how your solution looks like? What have you tried, what worked and what didn’t?</p>
<p>Also, please try compression on your websocket if you are concerned with payload sizes. IIRC I had 60-70% reduction when I tried it out.</p>
<aside class="quote no-group quote-modified" data-username="Schultzer" data-post="32" data-topic="69408">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/schultzer/48/4339_2.png" class="avatar"> Schultzer:</div>
<blockquote>
<p>I pay special attention to my html construction since that can have great importance an example is this issue <a href="https://github.com/patrick-steele-idem/morphdom/issues/228" rel="nofollow">Morphing page with a lot (1000 or so) FORM tags is slow · Issue #228 · patrick-steele-idem/morphdom · GitHub</a> which shows that having to many form elements slows the page.</p>
</blockquote>
</aside>
<p>Oh, what a great find! <a class="mention" href="/u/tmbb" rel="nofollow">@tmbb</a>, did you profile the performance across browsers? Is it the same in Chrome and Firefox? Also, is there a way for you to temporarily replace the <code>form</code> tag by <code>div</code> and see if it changes anything? You can open up <code>deps/phoenix_live_view</code>, change the <code>.form</code> component, do <code>mix deps.compile phoenix_live_view</code>, and try it out.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="356454" 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/liveview-performance-problems-morphdom-taking-up-to-1500ms-to-patch-updates/69408/33">Post #32</a>
	                </div>
	            </div>
              <div id="likers-container-356454" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="356454"
                     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 #32"></div>
  </section>
</div>
    <div class="postbit" id="356455" data-post-id="356455">
  <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 do cross browser testing, Safari is the best, and Chrome and Firefox is equal.</p>
<p>When it comes to highly optimized website with a lot of elements, like a database management tool, then the browser is less important, since the issues you are going to be hit by first is the browsers rendering engine.</p>
<p>So special attention on HTML construction and CSS is important. Tools like TailwindCSS and what not tend to get in the way, and hand written CSS and HTML tends to out win, due to the reduction of code needed to be written.</p>
<p>I mentioned Google Lighthouse, since it’s a fast and easy way to gain some insight. Vs having to spend time on interpreting a flamegraph.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="356455" 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/liveview-performance-problems-morphdom-taking-up-to-1500ms-to-patch-updates/69408/34">Post #33</a>
	                </div>
	            </div>
              <div id="likers-container-356455" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="356455"
                     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 #33"></div>
  </section>
</div>
    <div class="postbit" id="356457" data-post-id="356457">
  <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>FWIW, I asked Claude to build this small HTML page from the issue and I changed it to render inputs inside form. Firefox is about 5-6x slower when dealing with inputs (30ms for 1000 inputs), Chrome handles it about the same as everything else. However, Chrome is indeed much, much slower for forms.</p>
<pre data-code-wrap="html"><code class="lang-html">&lt;!doctype html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Morphdom Form Performance Test&lt;/title&gt;
    &lt;script src="https://cdn.jsdelivr.net/npm/morphdom@2.7.4/dist/morphdom-umd.min.js"&gt;&lt;/script&gt;
    &lt;style&gt;
      #metrics {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        background: #f0f0f0;
        padding: 10px;
        font-family: monospace;
        border-bottom: 1px solid #ccc;
        z-index: 100;
      }
      #main {
        margin-top: 60px;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id="metrics"&gt;
      Last render time: &lt;span id="renderTime"&gt;0&lt;/span&gt;ms | Average (last 5):
      &lt;span id="avgTime"&gt;0&lt;/span&gt;ms | Max time: &lt;span id="maxTime"&gt;0&lt;/span&gt;ms
    &lt;/div&gt;
    &lt;div id="main"&gt;&lt;/div&gt;

    &lt;script&gt;
      // Performance tracking
      const times = [];
      const maxSamples = 5;
      let maxTime = 0;

      function updateMetrics(renderTime) {
        times.push(renderTime);
        if (times.length &gt; maxSamples) times.shift();

        const avg = times.reduce((a, b) =&gt; a + b) / times.length;
        maxTime = Math.max(maxTime, renderTime);

        document.getElementById("renderTime").textContent = renderTime.toFixed(2);
        document.getElementById("avgTime").textContent = avg.toFixed(2);
        document.getElementById("maxTime").textContent = maxTime.toFixed(2);
      }

      window.addEventListener("load", (event) =&gt; {
        const el = document.getElementById("main");
        window.counter = 0;

        if (el) {
          window.inc = (e) =&gt; {
            if (e) e.preventDefault();
            window.counter += 1;

            const startTime = performance.now();
            morphdom(el, template());
            const endTime = performance.now();

            updateMetrics(endTime - startTime);
          };

          morphdom(el, template());
        }
      });

      function template() {
        const data = Array(2000)
          .fill()
          .map(() =&gt; `&lt;input name="input-${window.counter}" value="${window.counter}"&gt;&lt;/input&gt;`)
          .join("");

        return `
                &lt;div id="main"&gt;
                    Counter: ${window.counter}
                    &lt;a href="#" onclick="inc()"&gt;Increment&lt;/a&gt;
                    &lt;form&gt;
                    ${data}
                    &lt;/form&gt;
                &lt;/div&gt;
            `;
      }
    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;

</code></pre>
<p>I also asked it to generate a React app and the numbers are pretty much the same (slower for inputs), although I have no idea if the React app is decent or not: <a href="https://gist.github.com/josevalim/0a316a067895f3a98029c6bab2923de5" class="inline-onebox" rel="nofollow">react-app-patching.js · GitHub</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="356457" 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/liveview-performance-problems-morphdom-taking-up-to-1500ms-to-patch-updates/69408/35">Post #34</a>
	                </div>
	            </div>
              <div id="likers-container-356457" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="356457"
                     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 #34"></div>
  </section>
</div>
    <div class="postbit" id="356458" data-post-id="356458">
  <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>When it comes to rendering speed, Safari is the only game in town.</p>
<p>My best recommendation is to develop in Safari and test your website on FF and Chrome and adjust the differences there will be of your CSS.</p>
<p>If you are experiencing performance issue in Safari, it will be terrible in other browers.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="356458" 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/liveview-performance-problems-morphdom-taking-up-to-1500ms-to-patch-updates/69408/36">Post #35</a>
	                </div>
	            </div>
              <div id="likers-container-356458" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="356458"
                     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 #35"></div>
  </section>
</div>
    <div class="postbit" id="356459" data-post-id="356459">
  <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>For people wanting to go deeper, then I can highly recommend <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility" class="inline-onebox" rel="noopener nofollow ugc">content-visibility CSS property - CSS | MDN</a> which can increase rendering speed of dense pages a lot.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="356459" 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/liveview-performance-problems-morphdom-taking-up-to-1500ms-to-patch-updates/69408/37">Post #36</a>
	                </div>
	            </div>
              <div id="likers-container-356459" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="356459"
                     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 #36"></div>
  </section>
</div>
    <div class="postbit" id="356462" data-post-id="356462">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tozz" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tozz
                  </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="33" data-topic="69408">
<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>After reading <a class="mention" href="/u/tmjoen" rel="nofollow">@tmjoen</a>’s suggestion, I was thinking if something like that could be part of LiveView. Basically a way to say that a form is embedded in another form, and we could automatically stitch it back together. In pseudo-code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">&lt;form id="parent" phx-embeddable&gt;
  &lt;input name="posts" /&gt;
  ...
  &lt;!-- there may be a better tag --&gt;
&lt;/form&gt;

&lt;form phx-embed-at="#parent" phx-embed-as="posts[comments][0]"&gt;
  ...
&lt;/form&gt;
</code></pre>
<p>Then LiveView would put everything under the comments at “posts[comments][0]” for you, so you don’t have to do anything. Can you please tell us about how your solution looks like? What have you tried, what worked and what didn’t?</p>
<p>Also, please try compression on your websocket if you are concerned with payload sizes. IIRC I had 60-70% reduction when I tried it out.</p>
</blockquote>
</aside>
<p>Compression is the first thing I turn on, my only issue with it (not Phoenix related) is that it’s incredibly hard to get an actual size of the payload without using packet inspectors, web browsers just show the decompressed payloads <img src="https://forum.elixirforum.com/images/emoji/apple/confused.png?v=15" title=":confused:" class="emoji" alt=":confused:" loading="lazy" width="20" height="20"></p>
<p>To be honest, every solution I’ve tried has ending up being too complex for it to be worth it, and I’ve worked around it in terms of the product rather than the technical solution (as an example, disabled validation and only do it on save, partial forms where you only render one piece of the schema, make everything a livecomponent). I think a lot of it stems from not being able to to partial changesets, and I get why, but a lot of data comes in a list and most of the time you only change one of the list items, but you get it all back, and that is what causes the confusion I believe, the granularity of something like React doesn’t exist, again, I’m not saying it should, just that it’s not all that clear.</p>
<p>There’s also some strange things that happen that you would think shouldn’t. I have this super trivial components as an example.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def fa_icon(assigns) do
    ~H"""
    {App.Components.SVGIconLibrary.icon("fontawesome", @category, @name, class: @class)}
    """
  end
</code></pre>
<p>It just takes a name, a category and some classes, but even when nothing has changed you still get the entire element in the diff (see below), I understand it’s flagged as dynamic, but my initial understanding was that components that doesn’t change doesn’t get re-rendered, but maybe that’s just me <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>
<pre data-code-wrap="elixir"><code class="lang-elixir">"0": " value=\"2\"",
"1": {
    "0": " value=\"2\"",
    "1": {
        "0": "&lt;svg class=\"size-5 fill-red-400 hover:fill-red-700 cursor-pointer\" data-icon xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"&gt;&lt;path d=\"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z\"/&gt;&lt;/svg&gt;&lt;/svg&gt;",
        "s": 2
    },
    "2": "2",
    "3": " value=\"0.4\"",
    "s": 3
},
</code></pre>
<p>Now if you have a list of 100 items you get a 100 icons, which are all identical to the ones already in the markup.<br>
Then you also have things like this coming from just form handling in general</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">"0": {
    "s": 0,
    "d": [
        [
            " name=\"metric[thresholds][2][_persistent_id]\"",
            " value=\"2\""
        ],
        [
            " name=\"metric[thresholds][2][id]\"",
            " value=\"02312daf-fcb3-4ee4-afeb-6cac4922b1ec\""
        ]
    ]
},
</code></pre>
<p>Those will always be dynamic and that is quite the payload for something extremely basic. I get that they’re variables and considered dirty, but it’s frustrating to not be able to do anything about it. This is a classic example from a schema with “has_many” and using inputs_for, pretty standard. Now if you have a 100 threshold values even the absolute bare minimum on every validation call gets quite big.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="356462" 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/liveview-performance-problems-morphdom-taking-up-to-1500ms-to-patch-updates/69408/38">Post #37</a>
	                </div>
	            </div>
              <div id="likers-container-356462" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="356462"
                     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 #37"></div>
  </section>
</div>
    <div class="postbit" id="356463" data-post-id="356463">
  <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>You should rewrite your component and especially have as few dynamic parts as possible. In your example the whole function component is dynamic.</p>
<p>A function component should mostly be html, sprinkle with some dynamic elements, like the value of an input.</p>
<p>Do not use dynamic classes, write proper css instead.</p>
<p>An example of function components would be the core component module that are generated in a new Phoenix project.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="356463" 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/liveview-performance-problems-morphdom-taking-up-to-1500ms-to-patch-updates/69408/39">Post #38</a>
	                </div>
	            </div>
              <div id="likers-container-356463" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="356463"
                     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 #38"></div>
  </section>
</div>
    <div class="postbit" id="356464" data-post-id="356464">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>“proper css” sound fun, how do you write proper css for customizable components? This is not about simple things like “hidden” etc.</p>
<p>The core components are extremely dynamic, that’s why we have this entire thread… I don’t think there’s a single one that doesn’t re-render heavily actually.<br>
This is how core component icons look</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">&lt;span class={[@name, @class]} /&gt;
</code></pre>
<p>Literally a list with variables <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"></p>
<p>The idea with “few dynamic parts” sounds great in theory, but nobody has shown me it in reality in a Phoenix project.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="356464" 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/liveview-performance-problems-morphdom-taking-up-to-1500ms-to-patch-updates/69408/40">Post #39</a>
	                </div>
	            </div>
              <div id="likers-container-356464" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="356464"
                     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 #39"></div>
  </section>
</div>
    <div class="postbit" id="356465" data-post-id="356465">
  <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>Great point, and you’re right that the core components has a lot of dynamic parts when it comes to classes, that is mostly due to the use of TailwindCSS, you can match your CSS on pretty much anything <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors" class="inline-onebox" rel="noopener nofollow ugc">Attribute selectors - CSS | MDN</a></p>
<p>Tailwind is great as a learning resource and small projects, but you would be hard pressed by avoiding to learn CSS it is an essential part in understanding how the browser works.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="356465" 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/liveview-performance-problems-morphdom-taking-up-to-1500ms-to-patch-updates/69408/41">Post #40</a>
	                </div>
	            </div>
              <div id="likers-container-356465" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="356465"
                     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 #40"></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/69408/load_more?page=5">Load more posts (15 remaining)</a>
</div></template></turbo-stream>