Please watch the videos under Resources
before class.
Lighten the load!
In a recent objective we have updated our /planets
liveview to load planets on server start from an ETS table instead of a SQL table.
Today we will go one step further for LiveView optimization.
Consider what happens when we have a route that requires authentication:
IO.inspect socket
#Phoenix.LiveView.Socket<
id: "phx-GDarXadiVr3DggNC",
endpoint: AppWeb.Endpoint,
view: AppWeb.LectureLive.Show,
parent_pid: nil,
root_pid: #PID<0.808.0>,
router: AppWeb.Router,
assigns: %{
user: %App.Accounts.User{
__meta__: #Ecto.Schema.Metadata<:loaded, "users">,
id: 1,
admin: true,
email: "af033@bucknell.edu",
name: "Alexander Fuchsberger",
image: "1.jpeg",
enrollment: nil,
inserted_at: ~U[2025-02-24 14:24:33Z],
updated_at: ~U[2025-03-15 17:28:41Z]
},
# ...
We are storing the entire User struct in our LiveView!
In the video, we have learned that we would want to keep LiveViews at a bare minimum:
It would be much more desireable to only store the user_id
and retrieve the rest again when needed:
assigns: %{
user_id: 1
}
Storing just the ID allows us to at anytime retrieve the user struct again in the future, if we need it (for example on the settings page).
In other to make this performance improvement you will need to analyze UserAuth.ex
carefully together with your parnter and
- identify how
:current_user
gets stored into the socket's assigns - identify where
:current_user
in your application is being used - adapt such functions over multiple pages
Also be carefull to not confuse functions that work with connections conn
with functions that work with live_views (socket
). We don't need to optimize controllers because the moment the connection is sent to the client with the page response the webserver forgets about the request and leaves no memory footprint.
Todays objective is a reprensentative example for many similar optimization problems. To sum up the advantages and disadvantages of this particular change:
- reduce memory footprint of LiveSockets
- eliminates need to keep structure up to date in LiveSocket (reduces code complexity)
- adds a SQL query whenever we need the struct, typically in mount or handle_event functions. This adds code complexity and (unnoticably) increases the time it takes for such functions to complete.
Updating LiveViews that use the user struct (2 points)
We also want to use the new system in the settings page. You will need to reload the user struct:
# probably in mount/3:
user = socket.assigns.current_user # no longer works
user = Accounts.get_user(socket.assigns.user_id) # that should work now!
Make sure your pages are still functional after the ground-level change of switching to a user_id instead of a user struct! You will also want to maintain other pages that used the struct but for the purpose of objectives your partner will only test the settings page.
Testing (1 + 1 points)
Since we haven't given points for tests in a while and you might want to practice that for the extra credit points in the final project (can go beyond 100%) I also want you to update related tests. This is something we should always do as we develop and integrate new features in our application anyways.
Warning-Free compilation (1 point)
Completely unrelated but because I noticed several of you are collecting warnings at this point I would like to incentivice you to clean them up. Thus you will get a point if you can show (on localhost) that you can compile your application without warnings using the --force
option:
mix compile --force