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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="rhcarvalho" data-post="10" data-topic="65637">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/rhcarvalho/48/32243_2.png" class="avatar"> rhcarvalho:</div>
<blockquote>
<p>Typical LiveView applications have state, and that complicates the applicability of prefetching as others have mentioned.</p>
</blockquote>
</aside>
<p>Yes but that state is made of immutable data. Computing a new state doesn’t invalidate it. It’s more a question of not doing update in the database, using pubsub on so on.</p>
<p>So we can’t turn it on by default for all views but maybe it can be opt 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="354731" 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/add-an-option-to-prefetch-link-navigation/65637/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-354731" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="354731"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="354758" data-post-id="354758">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hexdocs is not liveview so it is a bad example to use for “liveview slow”.</p>
<p>Besides, I struggle with the “slow” argument. If your page rendering is 10ms you are looking at 10 ms + latency should, can be anything from 5 to 50ms.</p>
<p>So in total, you are looking at 15-60ms from the moment you click. I can’t see a reason why I would get into huge technical complexity to reduce that.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="354758" 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/add-an-option-to-prefetch-link-navigation/65637/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-354758" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="354758"
                     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 #12"></div>
  </section>
</div>
    <div class="postbit" id="354779" data-post-id="354779">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Prefetch in Next, Remix, etc. is generally applied on SSG content, not SSR AFAIK.</p>
<p>As mentioned above, a prefetched Liveview should not trigger any side effect and it may be hard to track. And the prefetch result should be invalidated at every state modification, I suppose.</p>
<p>However, I can imagine a world where, <strong>if every assign of the Liveview is <a href="https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#module-async-assigns" rel="noopener nofollow ugc">async</a> and rendered insided <code>.async_result</code></strong>, we might be able to load the static part of the DOM with the <code>.async_result</code> slots in a loading state. It might then be patched by classic Liveview mechanisms after an effective navigation.</p>
<p>In such a world, even <code>mount</code> should not run on prefetch to prevent any side effect. A prefetch would basically return the template with every <code>.async_result</code> in a loading state. Maybe we could imagine a <code>prefetch_default</code> option on <a href="https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#assign_async/4" rel="noopener nofollow ugc"><code>assign_async/4</code></a> if it is useful (right now I don’t find any use for it, even for skeleton purposes).</p>
<p>P.S: maybe that <code>prefetch_default</code> would be more useful on sync assigns to consider it “prefetch compatible” even if it not async.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="354779" 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/add-an-option-to-prefetch-link-navigation/65637/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-354779" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="354779"
                     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 #13"></div>
  </section>
</div>
    <div class="postbit" id="355603" data-post-id="355603">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Sure, 15-60ms is fine, and if you’re in the US or to a lesser extent europe that is probably what you’re going to get.</p>
<p>Unfortunately, a lot of apps cannot have distributed servers so the network round trip latency is going to have a much wider range than that. For example, at my company the servers must be in the EU but we have a significant percentage of the userbase in Australia. That means an absolute bare minimum of 400ms for half of our users which is a very bad experience. I’d love to use LiveView for this because I really prefer the DX but realistically this is forcing us to do an SPA because half a second for an page transition is just bad</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="355603" 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/add-an-option-to-prefetch-link-navigation/65637/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-355603" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="355603"
                     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 #14"></div>
  </section>
</div>
    <div class="postbit" id="355616" data-post-id="355616">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>There is no free lunch. Fetching the actual data will take 300ms regardless, wether you use an SPA or Liveview.</p>
<p>Liveview does provide some utilities to “fake” response UI stuff. Things like clicking a button and showing a spinner or a loading class on the button while you fetch the next view.</p>
<p>Do not underestimate the amount of money it costs to keep an SPA up to date. Just the maintenance is absolute hell.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="355616" 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/add-an-option-to-prefetch-link-navigation/65637/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-355616" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="355616"
                     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 #15"></div>
  </section>
</div>
    <div class="postbit" id="355866" data-post-id="355866">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>For writes you’re absolutely right, the best you can do is optimistic UI and spinners, but for reads you can get almost the same thing with an SPA by prefetching data. Usually, it takes one entire <code>client.prefetchQuery</code> inside a <code>requestIdleCallback</code>.</p>
<p>I am fully aware of the time cost of maintaining an SPA. I’ve been writing JS since we called interactive UI made without using flash or java “DHTML”, the number one way of fetching data on the client was jsonp and there was this exciting new function on the horizon called <code>document.querySelector</code>. If all you know is backend programming then yes it looks very scary but if you’re familiar with the environment and pin your dependencies frontend code is just as simple to maintain as backend code.</p>
<p>There is absolutely extra cost in developing the app, but there is also cost from lost productivity waiting for a loading spinner. There is a reason things like GraphQL/Relay exist and it is not for developer velocity. It is very easy to take loading times for granted if you live in the US or Europe where the servers are close.</p>
<p>If you watch <a href="https://i.byhemechi.com/livebeats-slow-transitions.mp4" rel="noopener nofollow ugc">this video</a> of me using livebeats, every one of these page transitions would benefit from prefetching page contents. This is pretty much the best case scenario for an Australian connection with gigabit fibre with good peering. Compare this to <a href="https://i.byhemechi.com/tidal-fast-transitions.mp4" rel="noopener nofollow ugc">this recording</a> of me using Tidal, an SPA and you can see the transitions are almost instant, despite the server also having ~300ms of latency, as demostrated by when I open a playlist that is yet to be cached.</p>
<p>Somewhat ironically, the same sort of speed can be achieved with phoenix, but only if you use “dead” views, because link <code>rel="prefetch"</code> works just fine for full page transitions</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="355866" 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/add-an-option-to-prefetch-link-navigation/65637/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-355866" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="355866"
                     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>