When using LiveView streams, inserting into DOM takes several seconds for some reason

Hi,

today I noticed a very strange issue and I don’t have any idea how to fix it, not even where to look to be honest.

I have a list of projects and I’m using streams to show them in the LiveView. Everything works just fine but for some reason, adding new project takes several seconds (5-7s) to be more precise, on localhost. As I fill the form with project data, new project is created right away in the DB and I get a flash notifying me that the new project has been created, that all happens instantly. After that, I have to wait several seconds, and then there is an update in console and project shows in the DOM. There are also no changes or updates in the terminal after the project is created initially.

defp save_product(socket, :new_product, product_params) do
    current_user = socket.assigns.current_user

    case Products.create_product(current_user, product_params) do
      {:ok, product} ->
        notify_parent({:product_saved, product})

        {:noreply,
          socket
          |> put_flash(:info, "Product created successfully")
          |> push_patch(to: ~p"/account")}

      {:error, %Ecto.Changeset{} = changeset} ->
        {:noreply, assign_form(socket, changeset)}
    end
  end

defp notify_parent(msg), do: send(self(), {__MODULE__, msg})

def handle_info({ProductFormComponent, {:product_saved, product}}, socket) do
    {:noreply, stream_insert(socket, :products, product)}
  end

After saving project to the DB, handle_info() function is run and that also happens right away so somewhere after stream_insert() and DOM update is a bottleneck.

I’ve tried different browser, restarting the server, computer, etc and it’s always the same and I have no idea what could be causing this.

Does anyone have any idea where should I even look?

What version of LV are you running?

Personally I had to push a PR to optimize phx-feedback that was causing issue, but it looks like the core team are scrapping the current solution.

Latest Elixir, Phoenix and Liveview (0.20.9).

Ugh, I’m not there yet, been working on a state of the art LV application, so can’t help you specifically, but I would recommend you to profile with firefox, then you are able to see where on the client there is a bottleneck. From my experience that is where the most common issues are, it’s rarely on the backend, but your design can definitely induce bottlenecks, if not careful and having to much chatter between server and client.

That’s odd. Could you share more code or even a small project to reproduce?

A huge shot in the dark: Do you have anything else messaging the LiveView process? Like when you save a project does it kick off other stuff that sends a bunch of message to the LiveView? It sort of sound like the inbox is backed up although that would be very strange and would have to be a bunch of slow stuff. I’ve heard of people doing all sorts of crazy things, though :slight_smile:

Hmm, try updating the socket changes only in the parent LiveView rather than in both the parent LiveView and child LiveComponent.

# child LiveComponent
defp save_product(socket, :new_product, product_params) do
    current_user = socket.assigns.current_user
    case Products.create_product(current_user, product_params) do
        {:ok, product} ->
            notify_parent({:product_saved, product})
            {:noreply, socket}
        {:error, %Ecto.Changeset{} = changeset} ->
            {:noreply, assign_form(socket, changeset)}
    end
end
# parent LiveView
def handle_info({ProductFormComponent, {:product_saved, product}}, socket) do
    updated_socket =
        socket
        |> put_flash(:info, "Product created successfully")
        |> push_patch(to: ~p"/account")}
        |> stream_insert(:products, product)

    {:noreply, updated_socket}
end
1 Like

I‘m seeing something similar in my application as well. I’ll try to investigate.

Nothing changes… form closes, flash shows and then couple of seconds later, project comes to DOM.

I just want to add that this is happening when inserting and editing the project, but not when deleting it. Also, there are only a couple of projects listed, 5-10.

How do I check that? Between saving the project and the DOM being updated, there is nothing in the console and nothing in the terminal.

[deleted]

I solved the issue finally, I had a function where I tried to hide the flash automatically after 5 seconds, it didn’t work properly but I forgot to remove it. Interestingly, this function which used JS.hide() with time option set to 5000ms, caused this issue.

1 Like

Check out Flashy for your notification auto-hiding needs.

1 Like

False alarm here as well. In my case the problem was caused by bad logic in a custom JS hook, nothing todo with streams.