perf: optimize map LiveView hot paths
Remove unused 30s timer, skip heatmap recluster on every single packet, trail dedup O(n^2)->O(n) Ultraworked with Sisyphus Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
ae1194ebb0
commit
e02fafc8da
3 changed files with 6 additions and 31 deletions
|
|
@ -161,7 +161,10 @@ defmodule AprsmeWeb.MapLive.DisplayManager do
|
|||
|
||||
defp trail_packets_for_callsign(visible_packets, historical_packets, callsign, threshold) do
|
||||
(Map.values(visible_packets) ++ Map.values(historical_packets))
|
||||
|> Enum.uniq_by(&trail_packet_key/1)
|
||||
|> Enum.reduce(%{}, fn p, acc ->
|
||||
Map.put_new(acc, trail_packet_key(p), p)
|
||||
end)
|
||||
|> Map.values()
|
||||
|> Enum.filter(&tracked_packet?(&1, callsign, threshold))
|
||||
|> Enum.sort_by(&packet_timestamp/1, :asc)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -141,8 +141,6 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
_ = Aprsme.StreamingPacketsPubSub.subscribe_to_bounds(self(), default_bounds)
|
||||
|
||||
_ = Process.send_after(self(), :cleanup_old_packets, 60_000)
|
||||
# Schedule UI update timer to refresh "time ago" display every 30 seconds
|
||||
_ = Process.send_after(self(), :update_time_display, 30_000)
|
||||
|
||||
socket
|
||||
|> assign(:spatial_client_id, client_id)
|
||||
|
|
@ -830,8 +828,6 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
|
||||
def handle_info(:cleanup_old_packets, socket), do: handle_cleanup_old_packets(socket)
|
||||
|
||||
def handle_info(:update_time_display, socket), do: handle_update_time_display(socket)
|
||||
|
||||
def handle_info(:reload_historical_packets, socket), do: handle_reload_historical_packets(socket)
|
||||
|
||||
def handle_info({:postgres_packet, packet}, socket) do
|
||||
|
|
@ -1743,13 +1739,6 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
{:noreply, assign(socket, :visible_packets, kept)}
|
||||
end
|
||||
|
||||
defp handle_update_time_display(socket) do
|
||||
# Schedule next update
|
||||
Process.send_after(self(), :update_time_display, 30_000)
|
||||
|
||||
{:noreply, assign(socket, :time_display_tick, System.monotonic_time())}
|
||||
end
|
||||
|
||||
defp handle_reload_historical_packets(socket) do
|
||||
require Logger
|
||||
|
||||
|
|
@ -1808,15 +1797,6 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
|
||||
# Helper functions for marker operations
|
||||
|
||||
@spec remove_markers_batch(Socket.t(), list()) :: Socket.t()
|
||||
defp remove_markers_batch(socket, []), do: socket
|
||||
|
||||
defp remove_markers_batch(socket, marker_ids) do
|
||||
Enum.reduce(marker_ids, socket, fn id, acc ->
|
||||
push_event(acc, "remove_marker", %{id: id})
|
||||
end)
|
||||
end
|
||||
|
||||
@spec add_markers_if_any(Socket.t(), list()) :: Socket.t()
|
||||
defp add_markers_if_any(socket, []), do: socket
|
||||
|
||||
|
|
@ -2014,7 +1994,7 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
|
||||
socket =
|
||||
socket
|
||||
|> remove_markers_batch(packets_to_remove)
|
||||
|> DisplayManager.remove_markers_batch(packets_to_remove)
|
||||
|> maybe_clear_historical_packets(bounds_state)
|
||||
|> push_event("filter_markers_by_bounds", %{bounds: map_bounds})
|
||||
|> assign(map_bounds: map_bounds, visible_packets: new_visible_packets)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ defmodule AprsmeWeb.MapLive.PacketProcessor do
|
|||
alias AprsmeWeb.Live.Shared.CoordinateUtils
|
||||
alias AprsmeWeb.Live.Shared.PacketUtils, as: SharedPacketUtils
|
||||
alias AprsmeWeb.MapLive.DataBuilder
|
||||
alias AprsmeWeb.MapLive.DisplayManager
|
||||
alias Phoenix.LiveView
|
||||
alias Phoenix.LiveView.Socket
|
||||
|
||||
|
|
@ -108,10 +107,7 @@ defmodule AprsmeWeb.MapLive.PacketProcessor do
|
|||
render_for_zoom(socket.assigns.map_zoom, marker_data, socket)
|
||||
end
|
||||
|
||||
# Zoom 8 and below use the heatmap instead of individual markers.
|
||||
defp render_for_zoom(zoom, _marker_data, socket) when zoom <= 8 do
|
||||
send_heat_map_for_current_bounds(socket)
|
||||
end
|
||||
defp render_for_zoom(zoom, _marker_data, socket) when zoom <= 8, do: socket
|
||||
|
||||
defp render_for_zoom(_zoom, nil, socket), do: socket
|
||||
|
||||
|
|
@ -224,10 +220,6 @@ defmodule AprsmeWeb.MapLive.PacketProcessor do
|
|||
Map.get(socket.assigns, :locale, "en")
|
||||
end
|
||||
|
||||
defp send_heat_map_for_current_bounds(socket) do
|
||||
DisplayManager.send_heat_map_for_current_bounds(socket)
|
||||
end
|
||||
|
||||
defp send_marker_with_popup_check(socket, marker_data) do
|
||||
# Strip convert_from — the single-packet JS handler uses its own scan logic.
|
||||
marker_data = Map.delete(marker_data, "convert_from")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue