anthropics / anthropics/claude-code

Claude Code Desktop: WindowServer at ~47% CPU while a response streams (deep CoreAnimation layer tree re-walked at 120 Hz)

Đang mở
#94,003 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
area:desktop bug has repro performance platform:macos
Ngôn ngữ chính
Python
Star
145k
Fork
23.1k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

## 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.

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
macos
Lĩnh vực
desktop, performance
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
45/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.