anthropics / anthropics/claude-code
Claude Code Desktop: WindowServer at ~47% CPU while a response streams (deep CoreAnimation layer tree re-walked at 120 Hz)
- Lingua principale
- Python
- Stelle
- 145k
- Fork
- 23.1k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
## Summary
While the Claude desktop app generates a response, macOS `WindowServer` runs at about 47% of one CPU core. The app window is otherwise cheap: with the app idle and the same window visible, `WindowServer` sits at 3-6%.
A stack sample of `WindowServer` shows the time goes into re-walking the Claude window's CoreAnimation layer tree, which nests about 50 levels deep, once per display refresh (120 Hz on this machine).
## Environment
- Claude desktop 1.52386.3
- macOS 26.6.2 (25G83)
- MacBook Pro, Apple M3 Pro, 14-core GPU
- Built-in Liquid Retina XDR display, 1512x982 points @ 3024x1964, 120 Hz
## Reproduce
1. Open the Claude desktop app with one window visible and nothing else on the space.
2. Record `WindowServer` CPU every 2 seconds.
3. Send a prompt that produces a long reply.
4. Compare the CPU while the reply streams against the CPU when the app is idle.
## Measurement
One continuous 2-minute trace. Nothing else changed. No other app window was on screen.
```
2s 48.5% previous reply still streaming
6s 34.0%
8s 8.0% streaming stops
12s 3.0%
...
54s 3.0% idle
58s 3.0%
60s 5.0%
62s 37.0% new reply starts streaming
64s 50.0%
73s 50.5%
87s 48.0%
101s 48.0%
105s 27.5% reply ends
111s 2.5%
121s 3.0% idle
```
Idle: 3-6%. Streaming: 41-51%.
## Stack sample
`sudo sample WindowServer 10`. All other WindowServer threads are idle; the render-server thread is blocked in `mach_msg` for 6440 of 6472 samples. All the time is on the main thread:
```
CGXRunOneServicesPass
post_port_data
non_coalesced_timer_handler
run_timer_pass
update_display_callback(void*, double) 2545
CGXUpdateDisplay 2544
WS::Updater::UpdateDisplays 2050
WS::Updater::prepare_coreanimation 1893
ca_prepare_begin_window_update(CGXWindow*) 1657
WSSessionConnectionPerformWithPluginOwner 1654
CARenderUpdateAddContext2 1487
CA::Render::Update::add_context 802
CA::Render::Updater::prepare_layer0 \
CA::Render::Updater::prepare_sublayer0 / ~50 levels of recursion
CA::Render::Updater::prepare_portal
```
One window accounts for this. The `ca_prepare_begin_window_update` branch with 1657 samples is the Claude window. Every other `ca_prepare_begin_window_update` branch in the sample has 20 samples or fewer.
## Attribution
- Hiding the Claude window (Command+H) during streaming takes `WindowServer` from 47% to 1.5%. Restoring it returns to 47%.
- Hiding every other application on the space changes nothing. Nine applications were eliminated one group at a time.
- A second Electron application was on screen for one round and contributed nothing measurable. This is specific to the Claude window.
- A shorter conversation does not help. A fresh session with a two-message transcript measured 51.2%.
- A smaller window costs less, consistent with fewer layers in the tree.
## Ruled out
Scaled display resolution (tested at native 1512x982 @ 3024x1964), video playback in another app, HID event rate (2.3 events/s), accessibility zoom and color filters (all off), EDR (headroom 1.0, inactive), Stage Manager (off), external displays (none), GPU saturation (10% device utilization), WindowServer log errors (none in 20 minutes).
## Expected
A streaming text animation should not require WindowServer to re-walk a 50-level layer tree at 120 Hz. Flattening the animated region into fewer composited layers, or confining the animation to its own layer, should remove most of this cost.
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Direzione di ricerca
Start by reproducing the reported macOS measurement on Claude desktop 1.52386.3: stream a long reply, record WindowServer CPU, and compare with idle and hidden-window behavior. Use the provided sudo sample WindowServer stack as the baseline; done means the streaming window no longer drives a repeated deep CoreAnimation layer-tree walk and WindowServer CPU drops near idle.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- macos
- Ambito
- desktop, performance
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Attiva
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 45/100