liveview-native / liveview-client-swiftui

MIT License
372 stars 35 forks source link

Client reconnects on backbutton #1312

Closed bcardarella closed 3 months ago

bcardarella commented 5 months ago

https://github.com/liveview-native/liveview-client-swiftui/assets/18524/7515af96-9380-43bc-96a5-8f0e8624c39b

I have a simple app with just a few routes:

  scope "/", DockyardDemoWeb do
    pipe_through :browser

    live "/", HomeLive
    live "/form", FormLive
    live "/map", MapLive
    live "/chart", ChartLive
    live "/video", VideoLive
    live "/tab", TabLive
  end

and a simple template:

<VStack class="background(Color.white) frame(minWidth:0,maxWidth:.infinity,minHeight:0,maxHeight:.infinity,alignment:.topLeading)">
  <.image url={~p"/images/native-logo.png"} class="frame(height:200)">
    <:success class="main-logo"/>
  </.image>

  <Text class="font(.title2)">Hello, ElixirConf EU!</Text>
  <.link navigate={~p"/form"}>Form</.link>
  <.link navigate={~p"/video"}>Video</.link>
  <.link navigate={~p"/map"}>Map</.link>
  <.link navigate={~p"/chart"}>Chart</.link>
  <.link navigate={~p"/tab"}>TabView</.link>
</VStack>

the LiveViews themselves and the target templates are effectively empty. When I navigate to another route then Back Button to the Home the re-render happens. I can see in the server log that a new Mount happens too:

[debug] MOUNT DockyardDemoWeb.HomeLive
  Parameters: %{"_format" => "swiftui"}
  Session: %{"_csrf_token" => "vgclOUUVzybKXTm6owJvH5LP"}
[debug] Replied in 81µs
[debug] MOUNT DockyardDemoWeb.FormLive
  Parameters: %{}
  Session: %{"_csrf_token" => "vgclOUUVzybKXTm6owJvH5LP"}
[debug] Replied in 137µs
[debug] MOUNT DockyardDemoWeb.HomeLive
  Parameters: %{"_format" => "swiftui"}
  Session: %{"_csrf_token" => "vgclOUUVzybKXTm6owJvH5LP"}
[debug] Replied in 194µs

What I suspect is happening is the cached page is showing and the sever then sends the page over the wire and this re-hydrates the View. In my case I have some animations that haven't been removed yet so I see the page jump.

Comparing this to the HTML LiveView the log looks slightly different:

[debug] MOUNT DockyardDemoWeb.HomeLive
  Parameters: %{}
  Session: %{"_csrf_token" => "5SCD7-Ue1rirY2qkmAsDjk38"}
[debug] Replied in 148µs
[debug] MOUNT DockyardDemoWeb.FormLive
  Parameters: %{}
  Session: %{"_csrf_token" => "5SCD7-Ue1rirY2qkmAsDjk38"}
[debug] Replied in 265µs
[debug] MOUNT DockyardDemoWeb.HomeLive
  Parameters: %{}
  Session: %{"_csrf_token" => "5SCD7-Ue1rirY2qkmAsDjk38"}
[debug] Replied in 131µs

If you follow each MOUNT you will see that for the first set from the SwiftUI client on the last MOUNT back to HomeLive it includes Parameters: %{"_format" => "swiftui} but this is not present for the HTML. I suspect we're doing a full reconnect and not staying within the socket lifecycle?

carson-katri commented 5 months ago

I think the flicker you're seeing is related to AsyncImage reloading after the document is parsed. In any case, we should remove the default animation from AsyncImage, or at least make it configurable.

carson-katri commented 3 months ago

AsyncImage was updated in #1351

bcardarella commented 3 months ago

Closed with #1351