Phoenix Dashboard and LiveView Optimization

DANA 325 O K R Q U T F S B A M D G N V W E X I C P H

Objectives

  • LiveViews should use user_id instead of :user or :current_user on all pages. Page should operate just like before so additional changes might be necessary depending on how often you used :current_user assign in your application. (2 Points)

  • Adapated UserAuth.ex so we still have 100% test coverage on all related tests. (1 Point)

  • /settings still works with new user_id system. Other pages that require the full user struct should be adapted accordingly but don't need to be verified for grading purposes. (2 Points)

  • Adapated SettingsLive tests so we still have 100% test coverage for tests on the settings page. (1 Point)

  • Show that your phoenix project compiles without warnings (1 Point)

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
Copyright © 2025 Alexander Fuchsberger, Bucknell University. All rights reserved.