KML MAP TOOL — DIAGNOSTIC TEST PLAN ==================================== Goal: isolate where pan/zoom lag actually originates (WebView vs app code vs data scale) before deciding which optimisation to invest in next. How to use: run sections in the order at the bottom of this file. Record FPS and console-counter numbers as you go. The numbers — not feel — decide what ships next. ------------------------------------------------------------------------------ A. WEBVIEW BASELINE TESTS (do first, cheapest) ------------------------------------------------------------------------------ A1. Confirm GPU acceleration Command: glxinfo | grep "OpenGL renderer" Pass: Output names a real GPU (e.g. "Mesa Intel(R) HD Graphics 630", "NVIDIA GeForce RTX 5070/PCIe/SSE2"). Fail: Output says "llvmpipe" (software rendering). If fail: No code change will help. Fix drivers / Mesa / permissions first. Stop here. A2. WebKitGTK DMA-BUF mitigation Run two sessions and compare FPS at the same dataset/zoom: Baseline: npm run tauri dev Mitigated: WEBKIT_DISABLE_DMABUF_RENDERER=1 npm run tauri dev Expected: FPS jumps >= 1.5x with the env var set on Linux + Mesa setups suffering DMA-BUF compositor regressions. If pass: WebKitGTK compositor is the bottleneck. Document the env var in INSTALLATION.md as a required workaround. A3. Tauri WKGTK vs Chromium A/B Terminal 1 (Tauri / WebKitGTK): npm run tauri dev Pan/zoom over a fixed area at z=14 for 5 seconds, record FPS. Terminal 2 (vanilla browser): npm run dev Open http://localhost:1420 in Firefox or Chromium. Login as "browser-test" (synthetic ~5000 dots around Hyderabad). Settings -> Performance mode ON (FPS counter top-centre). Pan/zoom at z=14 for 5 seconds, record FPS. Compare: same code, different WebView. Big delta = WebView is the bottleneck. Small delta = the issue is below the WebView (drivers/compositor/dataset). A4. Same build, cross-OS (if Windows machine available) Build / run the Tauri app on Windows (uses WebView2 = Chromium- based). Repeat A3 measurement with the same dataset. Pass: Windows holds steady FPS while Linux does not -> WebKitGTK is conclusively the issue on the user's Linux box. ------------------------------------------------------------------------------ B. APP-LEVEL ISOLATION (uses perfMode + console counters) ------------------------------------------------------------------------------ B1. perfMode on/off A/B 1. Settings -> Performance mode OFF. Pan/zoom 5 seconds. Record FPS. 2. Settings -> Performance mode ON. Pan/zoom 5 seconds. Record FPS. Big jump (>= +20 FPS): Layer complexity matters. Move to test B3 to find the most expensive layer. No change: Bottleneck is below the layer effect (WebView / Mesa / compositor). Move to A2/A3. B2. Console-count check 1. Open DevTools console. 2. Pan continuously for 5 seconds. Expected: "MapView render" increments by ~2 per gesture (movestart + moveend toggles). "deck layer rebuild" increments by <= 2 per gesture. Fail mode: either counter increments by tens or hundreds during a single pan -> a regression has snuck in. Investigate. B3. Layer-by-layer cost ladder (with perfMode OFF) Toggle right-panel Layer checkboxes off one at a time. Record FPS after each step: All on (baseline) FPS = ____ Scope off FPS = ____ Metadata off FPS = ____ OSM off FPS = ____ Range off FPS = ____ Fixed off FPS = ____ The biggest single-step jump = the layer to simplify first. B4. Filter-down ladder 1. Filter to a single video. Record FPS. 2. Then filter to a single asset_name. Record FPS. 3. Then zoom in by 2 levels. Record FPS. If FPS climbs sharply, dataset density is the load and the answer is zoom-tier sampling, not layer code. ------------------------------------------------------------------------------ C. SCENARIO REGRESSION TESTS (verify recent fixes) ------------------------------------------------------------------------------ C1. OSM import auto-recentre 1. Open app fresh (default viewport = [51.4, 25.5], near Qatar). 2. Do NOT pan. 3. Import an OSM GeoJSON for a far-away region (e.g. Hyderabad). Expected: map flies to imported region, roads visible immediately, status bar shows "Loaded N road segment(s). Centred on imported area." Fail: roads invisible after import. Was the user-reported bug "imports 10-15 times before showing". C2. Pan/zoom doesn't churn React 1. Open DevTools -> React DevTools -> Profiler. 2. Click record. Pan continuously 5 seconds. Stop record. Expected: <= 2 AppShell renders per gesture (movestart + moveend). Fail: ~60 renders/sec -> the move-sync regression is back. C3. Decorative overlays hide during gestures 1. Tap a metadata polyline to select it (arrows, S/E rings, name badge appear). 2. Begin a pan or zoom. Expected: arrows, name badge, S/E rings/labels, link halos disappear during the gesture and reappear on moveend. C4. zoomBand quantisation 1. Open DevTools console (counters visible from B2). 2. Mouse-wheel zoom by tiny increments within one 0.5-zoom band (e.g. 14.0 -> 14.1 -> 14.2 -> 14.3). Expected: "deck layer rebuild" does NOT increment for sub-band moves. It should only increment when crossing a 0.5 boundary. C5. Stale-fetch guard 1. Pan rapidly across many tiles for 10 seconds without stopping. Expected: assets array updates only with the latest viewport's data. No flicker of old viewports' points appearing late. C6. Compare mode default off 1. Open app fresh. 2. Inspect .map-area in DevTools. Expected: exactly one child rendered. Toggle the Compare checkbox in the Basemap panel and a second canvas mounts; uncheck it and the second canvas unmounts. C7. Browser-mode shim 1. npm run dev (no Tauri). 2. Open http://localhost:1420 in Firefox or Chromium. Expected: - Login screen lists one user "Browser Test", no console errors. - After login, ~5000 dots visible around Hyderabad. - Pan/zoom works. - Filtering, search, perfMode toggle all work. - Edit operations log "[browser-mode] invoke(...) is not stubbed" warnings — expected, those mutations are no-ops in browser mode. ------------------------------------------------------------------------------ D. STRESS / SCALE TESTS ------------------------------------------------------------------------------ D1. 50k assets in viewport 1. Import the largest realistic dataset. 2. Zoom out so most points are in viewport. 3. Pan across — measure FPS and frame consistency. Acceptable: >= 30 FPS with perfMode OFF >= 50 FPS with perfMode ON D2. Dense OSM (no class filter) 1. Import a full-city OSM GeoJSON WITHOUT the major-only filter (i.e. accept all road classes). 2. Zoom out to z=12. If FPS tanks: zoom-tier simplification (Test 4 plan in chat) or class-prune workflow is required for that workload. D3. Many metadata polylines 1. Import the per-video metadata JSON with 40+ tracks. 2. Zoom out to fit all tracks. Pan. With viewport-cull + zoom-decimation already in place, should still be smooth. If not, lower the per-track point cap or the global arrow cap. D4. Long edit session (memory leak check) 1. Drag 100 asset pins in succession. 2. Mix snap-to-road, side-toggle, rename, delete, restore, undo. 3. Watch memory in DevTools. Expected: heap stays stable. No leaks from event listeners or MapLibre Marker objects. ------------------------------------------------------------------------------ E. FEATURE SMOKE TESTS (run before any release) ------------------------------------------------------------------------------ For each, confirm the feature still works after recent edits. 1. Login + create user + switch user 2. Import fixed assets JSON -> markers visible 3. Import range assets JSON -> S/M/E lines visible 4. Import KML scope -> polygon visible, out-of-scope filter works 5. Import per-video metadata JSON -> coloured polylines visible 6. Import OSM GeoJSON -> roads visible AND map auto-centres (see C1) 7. Click asset -> image popup opens (popupEnabled on) 8. Drag pin -> asset moves, action appears in Recent actions 9. Lasso (circle / rect / polygon) -> bulk delete / set-scope / restore work 10. Find duplicates within viewport 11. Mark anchor -> drag -> Distribute correction 12. Auto-link in polygon (L<->R, by-video, nearest) 13. Right-click two assets -> manual link, pink line Right-click them again -> unlink 14. OSM edit mode -> drag vertex, shift-click + Del, simplify slider all work 15. Search by lat/lng -> red goto pin appears 16. Search by video name -> flies to video, highlights metadata track 17. Export Source JSON / GeoJSON / KML / CSV Round-trip: re-import the Source JSON cleanly 18. Settings: toggle popup, aspect ratio, snap-to-centerline names, perfMode 19. Undo last action -> state restored 20. Reset DB -> app empty, but classes.txt suggestions still load ------------------------------------------------------------------------------ RECOMMENDED RUN ORDER (fastest signal first) ------------------------------------------------------------------------------ 1. A1, A2 (5 min, no code touched) 2. B2 (1 min — confirms recent perf changes are working) 3. B1 (2 min — quantifies what perfMode buys) 4. A3 (10 min — Tauri vs Chromium) 5. B3 (10 min — which layer is most expensive) 6. C1 (1 min — verifies the OSM auto-recentre fix) 7. D1, D2, D3 (only if A2/A3 inconclusive) 8. E (full smoke) (before any release) ------------------------------------------------------------------------------ DECISION TREE ------------------------------------------------------------------------------ A2 alone fixes the user's lag -> ship the env var in INSTALLATION.md, done. A3 shows Chromium is dramatically faster -> plan browser-mode deployment for Linux QA reviewers (keep Tauri for the import operator). B3 isolates one heavy layer -> zoom-tier simplification for that layer only. B1 jump is large but A3 delta is small -> invest in zoom-tier simplification (Test 4 plan). None of the above conclusive -> re-run on the actual user hardware before investing further. ============================================================================== End of test plan. ==============================================================================