Kino.Input.text slow to render new input
clayscode opened this issue · comments
Hi all,
I'm having an issue with Kino.Input.text rendering the output very slowly. Sometimes I even have to click around the page a few times or move the element around before the input gets rendered.
Livebook Version: v0.10.0
Elixir Version: v1.15.2
Mix.install([
{:kino_db, "~> 0.2.1"},
{:postgrex, "~> 0.17"},
{:kino_explorer, "~> 0.1.4"},
{:adbc, "~> 0.1"}
])
alias Explorer.DataFrame, as: DF
alias Explorer.Series, as: Series
alias Explorer.Query, as: Query
frame = Kino.Frame.new()
button = Kino.Control.button("Click") |> Kino.render()
items = [[a: "a", b: "b"], [a: "c",b: "d"]]
Kino.animate(button, 0, fn _event, counter ->
new_counter = counter + 1
current = Enum.at(items, counter)
inputs = [
example_a: Kino.Input.text("Example a: ", default: "#{current[:a]}"),
example_b: Kino.Input.text("Example b: ", default: "#{current[:b]}")
]
form = Kino.Control.form(inputs, submit: "Send")
Kino.Frame.clear(frame)
Kino.Frame.render(frame, form)
{:cont, frame, new_counter}
end)
The purpose of the above is to iterate over some objects and fill in the default Kino.Input.text values with them. However, when the input boxes are rendered, they're blank and it often takes a few seconds the default values to show up. If I move the element up or down, they populate the input box immediately. The frame clear and render at the end isn't necessary - I was just trying to see if I could force the text to render some how. Any idea what might be going on?
animate
already keeps a frame for you, so I wonder if the issue is being caused by rendering the same frame twice. Try this instead:
button = Kino.Control.button("Click") |> Kino.render()
items = [[a: "a", b: "b"], [a: "c",b: "d"]]
Kino.animate(button, 0, fn _event, counter ->
new_counter = counter + 1
current = Enum.at(items, counter)
inputs = [
example_a: Kino.Input.text("Example a: ", default: "#{current[:a]}"),
example_b: Kino.Input.text("Example b: ", default: "#{current[:b]}")
]
form = Kino.Control.form(inputs, submit: "Send")
{:cont, form, new_counter}
end)
animate
already keeps a frame for you, so I wonder if the issue is being caused by rendering the same frame twice. Try this instead:button = Kino.Control.button("Click") |> Kino.render() items = [[a: "a", b: "b"], [a: "c",b: "d"]] Kino.animate(button, 0, fn _event, counter -> new_counter = counter + 1 current = Enum.at(items, counter) inputs = [ example_a: Kino.Input.text("Example a: ", default: "#{current[:a]}"), example_b: Kino.Input.text("Example b: ", default: "#{current[:b]}") ] form = Kino.Control.form(inputs, submit: "Send") {:cont, form, new_counter} end)
Still have the same issue with this code
Edit: Just to confirm it's not an issue with my browser, I switched from Firefox to Chrome, but still run into the same problem.
I think there is a race condition happening in
Lines 172 to 177 in f961f8d
When putting an inspect after output
def handle_call({:render, term, destination}, _from, state) do
output = Kino.Render.to_livebook(term) |> IO.inspect()
put_update(destination, state.ref, [output], :replace)
state = update_outputs(state, destination, fn _ -> [output] end)
{:reply, :ok, state}
end
it magically works :-D
Couldn't figure out the details yet.
Here is a simple way to reproduce the error:
frame = Kino.Frame.new()
Kino.Frame.render(frame, Kino.Input.text("Test"))
button = Kino.Control.button("Click") |> Kino.render()
items = [[a: "a", b: "b"], [a: "c",b: "d"]]
Kino.animate(button, 0, fn _event, counter ->
new_counter = counter + 1
current = Enum.at(items, counter)
inputs = [
example_a: Kino.Input.text("Example a: ", default: "#{current[:a]}"),
example_b: Kino.Input.text("Example b: ", default: "#{current[:b]}")
]
form = Kino.Control.form(inputs, submit: "Send")
{:cont, form, new_counter}
end)
In the latest Livebook nightly build, this example doesn't even work - the whole session crashes 😅
I think there is a race condition happening in
Lines 172 to 177 in f961f8d
When putting an inspect after output
def handle_call({:render, term, destination}, _from, state) do output = Kino.Render.to_livebook(term) |> IO.inspect() put_update(destination, state.ref, [output], :replace) state = update_outputs(state, destination, fn _ -> [output] end) {:reply, :ok, state} endit magically works :-D Couldn't figure out the details yet.
Here is a simple way to reproduce the error:
frame = Kino.Frame.new()Kino.Frame.render(frame, Kino.Input.text("Test"))
I can't replicate my issue with this code - this seems to render correctly. I checked out the .10 branch of both Livebook and Kino and changed it to output = Kino.Render.to_livebook(term) |> IO.inspect()
but that doesn't seem to resolve the issue with Kino.animate
@clayscode I pushed a fix to livebook main. Not sure if its the correct way to tackle the issue, but it works on my side.
Lets see what @jonatanklosko thinks :)
@jannikbecher your PR seems to fix my issue, awesome!