Skip to content

perf(map): VisionOverlay AR-kapalı idle render döngüsünü durdur#64

Merged
selimmujdeci merged 1 commit into
mainfrom
feat/visionoverlay-idle-loop-gate
Jul 12, 2026
Merged

perf(map): VisionOverlay AR-kapalı idle render döngüsünü durdur#64
selimmujdeci merged 1 commit into
mainfrom
feat/visionoverlay-idle-loop-gate

Conversation

@selimmujdeci

Copy link
Copy Markdown
Owner

Amaç

Tam ekran harita idle/park iken, kullanıcı dokunmazken ana thread'in ~yarısını + compositor'ı yakan birincil kök nedeni kapatmak. Kaynak, GÖREV 2 gerçek-cihaz kök-neden araştırmasında (DevTools + /proc trace) bulundu: VisionOverlay.renderAR always-on rAF döngüsü — FullMapView idle-gate (PR #61) değil.

Kök neden (kanıtlı)

VisionOverlay.renderAR 60 fps rAF döngüsü, AR/kamera KAPALIYKEN bile (!frame || !isHybrid || confidenceLevel==='off') requestAnimationFrame(renderAR) ile koşulsuz yeniden planlanıyordu. VisionOverlay FullMapView'de koşulsuz mount olduğundan, harita açıkken (çizim yapmasa da) her kare getContext('2d',{willReadFrequently:true}) (CPU-backed canvas) + getBoundingClientRect (layout) + clearRect yapıyordu.

Gerçek cihaz kanıtı (Xiaomi zircon, A/B — geri alınabilir DevTools trace)

Ölçüm VisionOverlay CANLI VisionOverlay ÖLÜ
Process CPU (/proc) 35% 20%
Main-thread CPU 11% 6%
gfx fps 5.2 0.3

→ Düzeltilince idle harita Ayarlar tabanına (~20%) + ~0-2 fps hedefine ulaşıyor.

Tam rapor: docs-local/device-runs/20260712T000500-map-idle-root-cause/ROOT_CAUSE_REPORT.md.

Değişiklik (atomik, tek dosya, tek satır davranış)

VisionOverlay.tsx off-branch: requestAnimationFrame(renderAR)rafRef.current = null (döngü durur).

  • Yeniden başlatma OTOMATİK: renderAR deps'i (isHybrid/confidenceLevel/vision.frame/currentLat/currentLon) değişince renderAR yeniden yaratılır → mevcut useEffect([renderAR]) döngüyü tekrar başlatır. AR/HYBRID navigasyon açılınca çizim döngüsü geri gelir.
  • Aktif AR çizim yolu DEĞİŞMEZ (satır 623 reschedule korunur) → şerit/ok/tabela çizimi aynen çalışır.
  • Aynı "reschedule etmeden dur → dep değişince effect restart" deseni satır ~550 (if(!canvas) return;) zaten kullanıyor. Zero-leak: unmount cleanup + rafRef=null. Yeni timer/rAF/bağımlılık yok.

Kapsam

Test / doğrulama

  • visionOverlayIdleLoopGate.test.ts (yeni, 5 kaynak-kilidi): off-branch'in döngüyü durdurduğunu (rafRef=null, requestAnimationFrame YOK), aktif yolun + restart useEffect'inin + cleanup'ın korunduğunu kilitler. ⚠️ Bu repo component testinde renderToStaticMarkup (SSR) kullanır → useEffect/rAF çalışmaz, jsdom'da createRoot yok; davranışsal rAF testi altyapıda mümkün değil, bu yüzden kaynak-kilidi (kusurun sessizce geri gelmesini engeller).
  • tsc temiz, tam suite 3234 yeşil, ESLint 0.

Ledger

#47 🔴 "cihazda test edilmedi" — kabul ölçütü: idle harita VisionOverlay rAF 0/sn, process CPU ≤20-22%, gfx ≤~2 fps; AR/HYBRID açılınca çizim çalışır; background/soak/crash regresyonsuz; Mali-400 (K24) ayrı doğrulama. Ölçümsüz 🟢 yapılmaz.

🤖 Generated with Claude Code

KÖK NEDEN (GÖREV 2 gerçek-cihaz kök-neden araştırması, DevTools + /proc trace):
VisionOverlay.renderAR 60fps rAF döngüsü, AR/kamera KAPALIYKEN bile
(!frame || !isHybrid || confidenceLevel==='off') requestAnimationFrame(renderAR)
ile KOŞULSUZ yeniden planlanıyordu. VisionOverlay FullMapView'de koşulsuz mount
olduğundan, tam ekran harita idle/park iken (çizim yapmasa da) her kare
getContext(willReadFrequently) + getBoundingClientRect + clearRect yapıp ana
thread'i ve compositor'ı boşa yüküyordu.

KANIT (gerçek Xiaomi cihaz, A/B, geri alınabilir DevTools trace):
 - rAF çağrılarının %84'ü VisionOverlay (~138/sn); FullMapView yalnız ~9/sn
   (settled'da 0 — PR #61 idle-gate zaten çalışıyor, sorun ayrı bileşendeydi).
 - VisionOverlay rAF canlı düşürülünce (settled idle harita):
   process 35%→20%, main-thread 11%→6%, gfx 5.2→0.3 fps
   → Ayarlar tabanına (~20%) + ~0-2fps hedefine ulaştı.

FIX (tek dosya, tek satır davranış): off-branch'te requestAnimationFrame(renderAR)
yerine rafRef.current = null → döngü DURUR. Yeniden başlatma OTOMATİK: renderAR
deps'i (isHybrid/confidenceLevel/vision.frame/currentLat/currentLon) değişince
renderAR yeniden yaratılır → mevcut useEffect([renderAR]) döngüyü tekrar başlatır.
Aktif AR çizim yolu (satır 623 reschedule) DEĞİŞMEZ → AR/navigasyon korunur.
Aynı "reschedule etmeden dur" deseni satır ~550 (if(!canvas) return) zaten var.

Test: visionOverlayIdleLoopGate.test.ts (yeni, 5 kaynak-kilidi) — bu repo component
testinde renderToStaticMarkup (SSR) kullanır, useEffect/rAF çalışmaz + jsdom'da
createRoot yok, o yüzden davranışsal rAF testi mümkün değil; kilit off-branch'e
requestAnimationFrame geri konmasını + aktif yolun bozulmasını engeller.

Kapsam-dışı dokunulmadı: FullMapView PR #61, GPS PR #62, native OBD/CAN, SQL,
Platform Kernel #55. tsc temiz, tam suite 3234 yeşil, eslint 0.
Ledger #47 🔴 (cihazda önce/sonra ölçüm bekliyor).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014VxojH1dYGXbiAxzETXm6r
@vercel

vercel Bot commented Jul 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
car-launcher-pro Ready Ready Preview, Comment Jul 12, 2026 12:46am
carospro Ready Ready Preview, Comment Jul 12, 2026 12:46am

@selimmujdeci selimmujdeci merged commit 36b401a into main Jul 12, 2026
8 checks passed
selimmujdeci pushed a commit that referenced this pull request Jul 12, 2026
Cihaz doğrulaması (Xiaomi 23090RA98I, CDP rAF-attribution) #61'i DÜŞÜRDÜ:
idle harita CPU 108% (main+#64 ile aynı), rAF 137/sn, idle-gate döngüsü hiç
uyumuyordu. Kök neden (CDP + geçici window instrumentation): isIdleNow %100
`hysteresis(wake<2500ms)` bloğunda takılı; wake 2.8/sn spam. onGPSLocation
displacement-wake accuracy-BLIND'dı → park GPS gürültüsü (accuracy 3m, ~3m
zıplama) "≥3m/≥5km/h" eşiğini geçip wake tetikliyor. #61 park tutucusu yalnız
isIdleNow (döngü çıkışı) tarafındaydı; wake girişi korunmamıştı → yarım fix.

Düzeltme: wake-tarafına isIdleNow ile tutarlı park tutucusu — park (nav/sürüş
yok + hız<STANDSTILL_KMH) hâlinde fix'in kendi doğruluk yarıçapı
(max(STANDSTILL_HOLD_M, accuracy)) altındaki kayma wake ETMEZ. Gerçek hareket
(hız≥1.5 veya yarıçap-üstü displacement) wake eder → takip/fail-soft korunur.

Düzeltme sonrası (aynı cihaz/yöntem): idle CPU 108%→21% (~5x, Ayarlar tabanı
seviyesi), rAF 137→3.3/sn (%97.6↓), idle-gate döngüsü 278→0/3sn (uyudu),
MapLibre native repaint 114→0.

Testler 25→30: yeni feedGps modeli GPS-wake yolunu simüle eder (eski testler
wake'i yalnız manuel çağırdığından bu bug'ı KAÇIRMIŞTI). R1-R5 wake-tarafı
tutucuyu kilitler.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ybpi6udk4t9bQwHuaYrVT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant