Skip to content

Commit 7e5a891

Browse files
committed
Publish Elixir: Why your LiveViews shall be minimal and fast
1 parent c303618 commit 7e5a891

1 file changed

Lines changed: 27 additions & 0 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
+++
2+
title = "Elixir: Why your LiveViews `mount/3` shall be minimal and fast"
3+
description = "Yeah, don't do it"
4+
date = 2025-11-24
5+
[taxonomies]
6+
tags = ["tip", "elixir", "phoenix", "liveview"]
7+
+++
8+
9+
## Context
10+
There's one thing that you may do when developping your first LiveView apps (or developping applications in the early days of LV) that may have important consequences in production, or even during development, which may also become a bit hard to track down.
11+
12+
The [LiveView documentation][0] is excellent and easy to read, and there's a good paragraph on async operations. But it may not stress out enough how having blocking operations in your `mount/3` callback may be a very terrible idea.
13+
14+
## Your page lifecycle
15+
`mount/3` is called two times: on your first page render, and another time when your socket gets connected, initially. Also, if your frontend disconnects and reconnects, `mount/3` will be called again.
16+
17+
So, let's say you have a typical CRUD app, with a query that would fetch records on the index action, and doing that query in `mount`. Almost sounds harmless, right?
18+
19+
But it would actually have a couple of effects.
20+
21+
After a successful deployment, with a substantial amount of users connected, their LiveViews would try to reconnect to the newly deployed backends, may take a while to reconnect, freeze the UI meanwhile, or even end up in a timeout state. Also, navigations between pages would be much slower and probably noticeable.
22+
23+
Also, in development, you would eventually trigger the code reloader, that would in turn kill and reset your current LiveView(s). potentially depleting your Ecto pool, and get a frozen UI that would eventually timeout, with a mysterious error in the JS logs (`Unable to join (timeout)`). It doesn't take more than a few tabs open or several active LiveViews to trigger this situation with the default setup of 10 connections.
24+
25+
Bottom line is: that particular callback should always be minimal, and you should always try to do things asynchronously as much as psosible. `start_async/3` and `assign_async/3` are excellent ways to help you do that. And to be fair, this is not a nice to have. It should be mandatory for all production apps and as such, treated as a high priority flaw to address.
26+
27+
[0]: https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html

0 commit comments

Comments
 (0)