diff --git a/docs/architecture/gpui-findings.md b/docs/architecture/gpui-findings.md index d378fa9..c457c41 100644 --- a/docs/architecture/gpui-findings.md +++ b/docs/architecture/gpui-findings.md @@ -1,7 +1,30 @@ # GPUI Framework — Detailed Findings -**Date:** 2026-03-19 -**Source:** Hands-on prototyping (ui-gpui/, 2,490 lines) + source code analysis of GPUI 0.2.2 + Zed editor +**Date:** 2026-03-19 (updated 2026-03-19 22:30) +**Source:** Hands-on prototyping (ui-gpui/, 2,490 lines) + source code analysis of GPUI 0.2.2 + Zed editor + 4 parallel research agents + +## BREAKTHROUGH: 4.5% → 0.83% CPU + +**The #1 optimization rule in GPUI:** Never make animated state an Entity CHILD of the view that renders it. Make it a PEER Entity that the view READS. + +``` +WRONG (4.5% CPU): + Workspace → ProjectGrid → ProjectBox → PulsingDot (child Entity) + cx.notify() on PulsingDot → mark_view_dirty walks ancestors + → Workspace dirty → refreshing=true → ALL .cached() children miss + +RIGHT (0.83% CPU): + Workspace → ProjectGrid → ProjectBox (reads BlinkState) + BlinkState (peer Entity, not child) + cx.notify() on BlinkState → only dirties views that .read(cx) it + → ProjectBox dirty, Workspace/ProjectGrid NOT dirty → siblings cached +``` + +Key mechanisms: +1. **`.cached(StyleRefinement::default())`** on Entity children → GPU scene replay (zero Rust code) +2. **Shared state Entity** instead of child Entity → isolates dirty propagation +3. **`mark_view_dirty()` walks ancestors** — this is GPUI's fundamental constraint +4. **`refreshing=true` on cache miss** cascades down → children can't cache if parent is dirty ## Overview