Skip to content

Commit 63c9e86

Browse files
authored
Make devices index view much faster by deferring filter loading (#2390)
Filter loading is now done using async. Filters are accessed via a button and slide-out pane. We don't need the values for the dropdown menus fully populated at the cost of rendering the device list. This should be a significant improvement since we've seen the alarms query be quite slow in production. That should also be addressed of course but this removes a lot of work from the critical path of this important view.
1 parent 7509ee9 commit 63c9e86

File tree

1 file changed

+33
-4
lines changed

1 file changed

+33
-4
lines changed

lib/nerves_hub_web/live/devices/index.ex

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ defmodule NervesHubWeb.Live.Devices.Index do
9797
|> assign(:sort_direction, "asc")
9898
|> assign(:paginate_opts, @default_pagination)
9999
|> assign(:firmware_versions, firmware_versions(product.id))
100-
|> assign(:platforms, Devices.platforms(product.id))
100+
|> assign(:platforms, [])
101101
|> assign(:show_filters, false)
102102
|> assign(:current_filters, @default_filters)
103103
|> assign(:currently_filtering, false)
@@ -107,15 +107,16 @@ defmodule NervesHubWeb.Live.Devices.Index do
107107
|> assign(:valid_tags, true)
108108
|> assign(:device_tags, "")
109109
|> assign(:total_entries, 0)
110-
|> assign(:current_alarms, Alarms.get_current_alarm_types(product.id))
111-
|> assign(:metrics_keys, Metrics.default_metrics())
112-
|> assign(:deployment_groups, ManagedDeployments.get_deployment_groups_by_product(product))
110+
|> assign(:current_alarms, [])
111+
|> assign(:metrics_keys, [])
112+
|> assign(:deployment_groups, [])
113113
|> assign(:available_deployment_groups_for_filtered_platform, [])
114114
|> assign(:target_deployment_group, nil)
115115
|> assign(
116116
:soft_deleted_devices_exist,
117117
Devices.soft_deleted_devices_exist_for_product?(product.id)
118118
)
119+
|> assign(:filters_ready?, false)
119120
|> subscribe_and_refresh_device_list_timer()
120121
|> ok()
121122
end
@@ -135,6 +136,7 @@ defmodule NervesHubWeb.Live.Devices.Index do
135136
|> assign(:params, unsigned_params)
136137
|> assign_display_devices()
137138
|> maybe_assign_available_deployment_groups_for_filtered_platform()
139+
|> assign_filter_data()
138140
|> noreply()
139141
end
140142

@@ -451,6 +453,18 @@ defmodule NervesHubWeb.Live.Devices.Index do
451453
end
452454
end
453455

456+
defp assign_filter_data(%{assigns: %{product: product}} = socket) do
457+
socket
458+
|> start_async(:update_filter_data, fn ->
459+
[
460+
current_alarms: Alarms.get_current_alarm_types(product.id),
461+
metrics_keys: Metrics.default_metrics(),
462+
deployment_groups: ManagedDeployments.get_deployment_groups_by_product(product),
463+
platforms: Devices.platforms(product.id)
464+
]
465+
end)
466+
end
467+
454468
defp assign_display_devices(%{assigns: %{product: product, paginate_opts: paginate_opts, user: user}} = socket) do
455469
opts = %{
456470
pagination: %{page: paginate_opts.page_number, page_size: paginate_opts.page_size},
@@ -500,6 +514,21 @@ defmodule NervesHubWeb.Live.Devices.Index do
500514
|> noreply()
501515
end
502516

517+
def handle_async(:update_filter_data, {:ok, new_assigns}, socket) do
518+
socket
519+
|> assign(new_assigns)
520+
|> assign(:filters_ready?, true)
521+
|> noreply()
522+
end
523+
524+
def handle_async(:update_filter_data, {:exit, reason}, socket) do
525+
message =
526+
"Live.Devices.Index.handle_async:update_filter_data failed due to exit: #{inspect(reason)}"
527+
528+
{:ok, _} = Sentry.capture_message(message, result: :none)
529+
socket
530+
end
531+
503532
defp device_pagination_assigns(socket, paginate_opts, pager) do
504533
paginate_opts =
505534
paginate_opts

0 commit comments

Comments
 (0)