I ran a little experiement to see which approach was quickest:
A combination approach (4) seems to be quickest becaues I saved by not duplicating quicker queries, and also loading slower queries asynchronously. Had my page been a public page, then I would have stuck with option 3 - Using async_assigns on mount.
Unless you’re much more experienced than I am, using async_assigns can feel a bit tedious - so, reserving it for slower running queries seems to pay the most dividends. This is also why I like the combination approach.
After I published this post, I learned about async_assigns from the amazing Elixir community on Reddit:
which provide a more elegant solution to dealing with slow loading data. The following, then, is the less elegant approach.
def mount(params, _session, socket) do
# If this is the first pass
if not connected?(socket) do
# assigns for static render go here
{:ok, render_with(&alt_render_method/1)}
else
# database loads and assigns for
# dynamic render go here
{:ok, socket}
end
end
def mount(params, _session, socket) do
if not is_connected?(socket) do
{ :ok,
socket
|> assign(
basic_info_that_needs_to_be_shown: load_basic_stuff(),
data_heavy_things: [])}
else
# dynamic load
{ :ok,
socket
|> assign(
basic_info_that_needs_to_be_shown: load_basic_stuff(),
data_heavy_things: load_all_the_heavier_stuff())}
end
end
defp load_basic_stuff(socket) do
# ...
end
defp load_all_the_heavier_stuff(socket) do
# ...
end
def mount(params, _session, socket) do
if not is_connected?(socket) do
# assigns for static render go here
# instead of returning {:ok, socket}, use render_with() to render
# different function for the static pass.
{ :ok,
socket
|> assign(
basic_info_that_needs_to_be_shown: load_basic_stuff(),
data_heavy_things: [])
|> render_with(&alt_render/1)}
else
# dynamic load
{ :ok,
socket
|> assign(
basic_info_that_needs_to_be_shown: load_basic_stuff(),
data_heavy_things: load_all_the_heavier_stuff())}
end
end
def alt_render(assigns) do
~H"""
<div>
Loading....
</div>
"""
end
def render(assigns) do
# Your usual render
end