From 2adc0a9fcb01af22dee21ef475d1d85bf422d7c7 Mon Sep 17 00:00:00 2001 From: "Tanner Collin (aider)" Date: Thu, 14 Aug 2025 20:25:18 +0000 Subject: [PATCH] perf: memoize coordinate processing to prevent UI freeze --- mapper/src/App.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/mapper/src/App.js b/mapper/src/App.js index 8ee2f69..9ceec98 100644 --- a/mapper/src/App.js +++ b/mapper/src/App.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from 'react'; +import React, { useState, useEffect, useRef, useMemo } from 'react'; import * as leaflet from 'leaflet'; import { MapContainer, Polyline, TileLayer, useMap, useMapEvents } from 'react-leaflet'; import Datetime from 'react-datetime'; @@ -153,9 +153,22 @@ function FitBounds({ coords, mapState, end, duration }) { function Map({end, duration, slider, mapState, setMapState}) { const [data, loading] = useSensor('owntracks', 'OwnTracks', end, duration); - const range = parseSlider(end, duration, slider); + const range = useMemo(() => parseSlider(end, duration, slider), [end, duration, slider]); - const coords = data.length ? data.filter(x => !range || (x.time >= range[0] && x.time <= range[1])).map(({ lat, lon }) => [lat, lon]).filter(([lat, lon]) => typeof lat === 'number' && typeof lon === 'number' && isFinite(lat) && isFinite(lon)) : []; + const coords = useMemo(() => { + if (!data || !data.length) return []; + + const result = []; + for (const point of data) { + if ((!range || (point.time >= range[0] && point.time <= range[1]))) { + const { lat, lon } = point; + if (typeof lat === 'number' && typeof lon === 'number' && isFinite(lat) && isFinite(lon)) { + result.push([lat, lon]); + } + } + } + return result; + }, [data, range]); const handleSubmit = (e) => { e.preventDefault();