[object Object]

← back to Homesonspec

mobile: cap rendered map markers (120, densest-first) + lower grid density — fix react-native-maps on-device OOM crash on the Map tab (TK-11155)

4df903f18a2617f44705b6e110079bda5779ed16 · 2026-09-04 08:20:53 -0700 · Steve

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQi5poZk3YeUbEJbDcFRmc

Files touched

Diff

commit 4df903f18a2617f44705b6e110079bda5779ed16
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Sep 4 08:20:53 2026 -0700

    mobile: cap rendered map markers (120, densest-first) + lower grid density — fix react-native-maps on-device OOM crash on the Map tab (TK-11155)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01CQi5poZk3YeUbEJbDcFRmc
---
 apps/mobile/app/(tabs)/map.tsx | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/apps/mobile/app/(tabs)/map.tsx b/apps/mobile/app/(tabs)/map.tsx
index a5515d10..b7b0e79f 100644
--- a/apps/mobile/app/(tabs)/map.tsx
+++ b/apps/mobile/app/(tabs)/map.tsx
@@ -50,8 +50,13 @@ const DEFAULT_REGION: Region = {
 };
 
 // Clustering grid resolution (cells across the visible span) and edge padding.
-const GRID_CELLS = 14;
+const GRID_CELLS = 10;
 const BBOX_PAD = 0.2; // 20% padding around the visible region → no edge pop-in
+// Hard cap on rendered markers. react-native-maps holds a native custom view per
+// marker and OOM-crashes on the physical device when too many custom-view markers
+// (each with a Callout) are mounted at once — so we render at most this many, the
+// densest clusters first. The "All (N)" total count is unaffected (it's separate).
+const MAX_MARKERS = 120;
 
 type Cluster = {
   key: string;
@@ -153,10 +158,13 @@ export default function MapTab() {
   }, [load]);
 
   // Recompute clusters only when the data, filter, or SETTLED region changes.
-  const clusters = useMemo(
-    () => clusterMarkers(markers, region, filterStatus),
-    [markers, region, filterStatus],
-  );
+  const clusters = useMemo(() => {
+    const all = clusterMarkers(markers, region, filterStatus);
+    // Bound the native custom-view marker count to avoid an on-device OOM crash;
+    // when a viewport would produce more, keep the densest clusters.
+    if (all.length <= MAX_MARKERS) return all;
+    return all.sort((a, b) => b.count - a.count).slice(0, MAX_MARKERS);
+  }, [markers, region, filterStatus]);
 
   const filterKeys: Array<string | null> = ['MOVE_IN_READY', 'UNDER_CONSTRUCTION', 'PLANNED', null];
 

← f2de197d Homes on Spec: actually test the tracker-blocking script (TK  ·  back to Homesonspec  ·  auto-data-snapshot: 2026-09-04T08:26:29 (1 data files) — app 46e6b219 →