performance improvements
This commit is contained in:
parent
c2b224096c
commit
1406ae97f0
3 changed files with 60 additions and 57 deletions
|
|
@ -180,7 +180,7 @@ let liveSocket = new LiveSocket("/live", Socket, {
|
||||||
|
|
||||||
// Show progress bar on live navigation and form submits
|
// Show progress bar on live navigation and form submits
|
||||||
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
|
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
|
||||||
window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
|
window.addEventListener("phx:page-loading-start", _info => topbar.show(100))
|
||||||
window.addEventListener("phx:page-loading-stop", _info => topbar.hide())
|
window.addEventListener("phx:page-loading-stop", _info => topbar.hide())
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -412,9 +412,10 @@ defmodule Aprsme.Packets do
|
||||||
def get_recent_packets_optimized(opts \\ %{}) do
|
def get_recent_packets_optimized(opts \\ %{}) do
|
||||||
# Always limit to the last hour for initial load
|
# Always limit to the last hour for initial load
|
||||||
one_hour_ago = DateTime.add(DateTime.utc_now(), -3600, :second)
|
one_hour_ago = DateTime.add(DateTime.utc_now(), -3600, :second)
|
||||||
limit = Map.get(opts, :limit, 500)
|
limit = Map.get(opts, :limit, 200)
|
||||||
|
|
||||||
# Use a more efficient query that leverages the partial indexes
|
# Use a more efficient query that leverages the partial indexes
|
||||||
|
# Order by received_at DESC to get the most recent packets first
|
||||||
base_query =
|
base_query =
|
||||||
from(p in Packet,
|
from(p in Packet,
|
||||||
where: p.has_position == true,
|
where: p.has_position == true,
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
if connected?(socket) do
|
if connected?(socket) do
|
||||||
Endpoint.subscribe("aprs_messages")
|
Endpoint.subscribe("aprs_messages")
|
||||||
Phoenix.PubSub.subscribe(Aprsme.PubSub, "postgres:aprsme_packets")
|
Phoenix.PubSub.subscribe(Aprsme.PubSub, "postgres:aprsme_packets")
|
||||||
maybe_start_geolocation(socket)
|
# Defer IP geolocation to avoid blocking initial page load
|
||||||
|
Process.send_after(self(), :start_geolocation, 2000)
|
||||||
end
|
end
|
||||||
|
|
||||||
{:ok,
|
{:ok,
|
||||||
|
|
@ -90,53 +91,6 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec maybe_start_geolocation(Socket.t()) :: Socket.t()
|
|
||||||
defp maybe_start_geolocation(socket) do
|
|
||||||
if geolocation_enabled?() do
|
|
||||||
ip_for_geolocation =
|
|
||||||
if Application.get_env(:aprsme, AprsmeWeb.Endpoint)[:code_reloader] do
|
|
||||||
# For testing geolocation in dev environment, use a public IP address.
|
|
||||||
# This will be geolocated to Mountain View, CA.
|
|
||||||
"8.8.8.8"
|
|
||||||
else
|
|
||||||
extract_ip(socket)
|
|
||||||
end
|
|
||||||
|
|
||||||
if valid_ip_for_geolocation?(ip_for_geolocation) do
|
|
||||||
start_geolocation_task(ip_for_geolocation)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
socket
|
|
||||||
end
|
|
||||||
|
|
||||||
defp geolocation_enabled? do
|
|
||||||
Application.get_env(:aprsme, :disable_aprs_connection, false) != true
|
|
||||||
end
|
|
||||||
|
|
||||||
defp extract_ip(socket) do
|
|
||||||
case socket.private[:connect_info][:peer_data][:address] do
|
|
||||||
{a, b, c, d} -> "#{a}.#{b}.#{c}.#{d}"
|
|
||||||
{a, b, c, d, e, f, g, h} -> "#{a}:#{b}:#{c}:#{d}:#{e}:#{f}:#{g}:#{h}"
|
|
||||||
_ -> nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp valid_ip_for_geolocation?(ip) do
|
|
||||||
ip && !String.starts_with?(ip, "127.") && !String.starts_with?(ip, "::1")
|
|
||||||
end
|
|
||||||
|
|
||||||
defp start_geolocation_task(ip) do
|
|
||||||
Task.start(fn ->
|
|
||||||
try do
|
|
||||||
get_ip_location(ip)
|
|
||||||
rescue
|
|
||||||
_error ->
|
|
||||||
send(self(), {:ip_location, @default_center})
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("bounds_changed", %{"bounds" => bounds}, socket) do
|
def handle_event("bounds_changed", %{"bounds" => bounds}, socket) do
|
||||||
handle_bounds_update(bounds, socket)
|
handle_bounds_update(bounds, socket)
|
||||||
|
|
@ -211,8 +165,8 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
def handle_event("map_ready", _params, socket) do
|
def handle_event("map_ready", _params, socket) do
|
||||||
socket = assign(socket, map_ready: true)
|
socket = assign(socket, map_ready: true)
|
||||||
|
|
||||||
# Always trigger reload of historical packets with the current value
|
# Load historical packets with a small delay to ensure map is fully ready
|
||||||
send(self(), :reload_historical_packets)
|
Process.send_after(self(), :reload_historical_packets, 100)
|
||||||
|
|
||||||
# If we have pending geolocation, zoom to it now
|
# If we have pending geolocation, zoom to it now
|
||||||
socket =
|
socket =
|
||||||
|
|
@ -317,6 +271,8 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
|
|
||||||
def handle_info({:postgres_packet, packet}, socket), do: handle_info_postgres_packet(packet, socket)
|
def handle_info({:postgres_packet, packet}, socket), do: handle_info_postgres_packet(packet, socket)
|
||||||
|
|
||||||
|
def handle_info(:start_geolocation, socket), do: handle_info_start_geolocation(socket)
|
||||||
|
|
||||||
def handle_info(%Phoenix.Socket.Broadcast{topic: "aprs_messages", event: "packet", payload: packet}, socket),
|
def handle_info(%Phoenix.Socket.Broadcast{topic: "aprs_messages", event: "packet", payload: packet}, socket),
|
||||||
do: handle_info({:postgres_packet, packet}, socket)
|
do: handle_info({:postgres_packet, packet}, socket)
|
||||||
|
|
||||||
|
|
@ -454,6 +410,52 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
{:noreply, assign(socket, visible_packets: new_visible_packets)}
|
{:noreply, assign(socket, visible_packets: new_visible_packets)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp handle_info_start_geolocation(socket) do
|
||||||
|
if geolocation_enabled?() do
|
||||||
|
ip_for_geolocation =
|
||||||
|
if Application.get_env(:aprsme, AprsmeWeb.Endpoint)[:code_reloader] do
|
||||||
|
# For testing geolocation in dev environment, use a public IP address.
|
||||||
|
# This will be geolocated to Mountain View, CA.
|
||||||
|
"8.8.8.8"
|
||||||
|
else
|
||||||
|
extract_ip(socket)
|
||||||
|
end
|
||||||
|
|
||||||
|
if valid_ip_for_geolocation?(ip_for_geolocation) do
|
||||||
|
start_geolocation_task(ip_for_geolocation)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp geolocation_enabled? do
|
||||||
|
Application.get_env(:aprsme, :disable_aprs_connection, false) != true
|
||||||
|
end
|
||||||
|
|
||||||
|
defp extract_ip(socket) do
|
||||||
|
case socket.private[:connect_info][:peer_data][:address] do
|
||||||
|
{a, b, c, d} -> "#{a}.#{b}.#{c}.#{d}"
|
||||||
|
{a, b, c, d, e, f, g, h} -> "#{a}:#{b}:#{c}:#{d}:#{e}:#{f}:#{g}:#{h}"
|
||||||
|
_ -> nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp valid_ip_for_geolocation?(ip) do
|
||||||
|
ip && !String.starts_with?(ip, "127.") && !String.starts_with?(ip, "::1")
|
||||||
|
end
|
||||||
|
|
||||||
|
defp start_geolocation_task(ip) do
|
||||||
|
Task.start(fn ->
|
||||||
|
try do
|
||||||
|
get_ip_location(ip)
|
||||||
|
rescue
|
||||||
|
_error ->
|
||||||
|
send(self(), {:ip_location, @default_center})
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
# Handle replaying the next historical packet
|
# Handle replaying the next historical packet
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
|
@ -921,8 +923,8 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
# Clear existing historical packets
|
# Clear existing historical packets
|
||||||
socket = push_event(socket, "clear_historical_packets", %{})
|
socket = push_event(socket, "clear_historical_packets", %{})
|
||||||
|
|
||||||
# Load historical packets for the current map bounds and time range
|
# Use optimized loading for better performance
|
||||||
socket = load_historical_packets_for_bounds(socket, socket.assigns.map_bounds)
|
socket = load_historical_packets_for_bounds_optimized(socket, socket.assigns.map_bounds)
|
||||||
|
|
||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
else
|
else
|
||||||
|
|
@ -1112,14 +1114,14 @@ defmodule AprsmeWeb.MapLive.Index do
|
||||||
map_bounds.north
|
map_bounds.north
|
||||||
]
|
]
|
||||||
|
|
||||||
# Use the optimized query for initial load
|
# Use the optimized query for initial load with smaller limit for faster loading
|
||||||
packets_module = Application.get_env(:aprsme, :packets_module, Aprsme.Packets)
|
packets_module = Application.get_env(:aprsme, :packets_module, Aprsme.Packets)
|
||||||
|
|
||||||
historical_packets =
|
historical_packets =
|
||||||
packets_module.get_recent_packets_optimized(%{
|
packets_module.get_recent_packets_optimized(%{
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
# Smaller limit for faster initial load
|
# Reduced limit for faster initial load
|
||||||
limit: 500
|
limit: 200
|
||||||
})
|
})
|
||||||
|
|
||||||
if Enum.empty?(historical_packets) do
|
if Enum.empty?(historical_packets) do
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue