Quiet by default: what a Mac app should do at idle
We measure idle CPU for every MacSuite app. One finding — rolling digits on live readouts cost Procowl about 24% CPU at idle until we limited them.
The MacSuite team
2 min read
On this page
An app you aren't looking at should cost almost nothing. That sounds obvious, but it's easy to break without noticing: an animation that keeps running behind a closed window, a timer that never stops, a view that redraws every second.
So every MacSuite app has the same rule: keep idle CPU at about zero. No repeating animation or timer runs while the window is hidden.
How we check
After each round of work, every app is built, launched normally and left alone, and its CPU use is measured. In the latest round all eight apps idled at about 0–1%.
That number didn't come for free. One app failed the check.
The finding: rolling digits
Procowl is an activity monitor, so its screen is full of live numbers. In its new design those numbers rolled from one value to the next, like an odometer, using SwiftUI's numeric-text content transition — roughly like this:
Text(value, format: .percent)
.monospacedDigit()
.contentTransition(.numericText(value: value))It looked good. It also kept Procowl at roughly a quarter of a CPU core while idle — about 24% in our measurement — in both Debug and Release builds.
We found the cause by switching features off one at a time with environment flags. The rolling transition is drawn on the CPU with a blur for a fraction of a second every time a value changes. On a live monitor, a handful of figures change every second or two, so that cost never stops.
The fix
Rolling digits are now opt-in, and Procowl uses them for a single large detail number instead of every live figure. Idle CPU dropped to under 1%.
The shared component that wraps this effect now carries the warning in its documentation: use it for values that change on user actions or rarely, such as scan totals or counts — never for per-sample live readouts.
The general lessons
- Measure idle, every time. This problem was invisible in screenshots and tests; only launching the app and watching it showed it.
- Live data and decorative animation don't mix by default. Anything that animates per update multiplies by the update rate.
- Pause when hidden. Procowl's breathing tiles pause when the window is hidden or Reduce Motion is on, and its timeline chart stops refreshing while the window is hidden. The design rules for every app forbid repeating animations or timers while a window is hidden.