daveebbelaar/bama

performance

Make a macOS app fast by measuring hangs, stutter, CPU, memory, and energy, then moving work off the main thread and onto the GPU.

ソースを見る

使い方

  1. インストールコマンドをコピーし、自分の環境へ導入する前にソースを確認します。
  2. 必要なツール、認証情報、対応環境を原文で確認します。
  3. 入力と成果物を指定し、出力を資料と照合します。
npx skills add https://github.com/daveebbelaar/bama --skill performance

開始前の確認

  • 導入にはモデル契約、API枠、ファイルへのアクセス許可は含まれません。
  • スター数や導入数は活動の指標であり、独立した品質・安全性試験ではありません。
リポジトリの原文

見出し、例、コード、表、リンク、参照画像を含む原文を表示しています。

Performance

Fast means two numbers: the first frame after a key press shows in under 100 ms, and nothing on the main thread blocks for more than 50 ms. Every change in this skill starts and ends with a measurement, so you know it helped. Symptom-by-symptom fixes are in recipes.md. For video, audio, camera, Metal, or large image pipelines, also read gpu-media.md.

The loop

text
reproduce -> measure (release build) -> find the line -> fix -> measure again -> commit with the numbers
  1. Reproduce. Write the exact steps, or add a probe command to the

debug bridge (test-mac-app skill) that runs the slow action and logs the time of each step.

  1. Measure the release build. Debug Swift is 3 to 10 times slower and

points at the wrong code.

  1. Find the line. Pick the tool for the symptom:
SymptomTool
App freezes, spinning pointersample <App> 5, then read the main thread stack
Slow actionTime Profiler: xcrun xctrace record --template 'Time Profiler' --attach <App> --time-limit 10s
Short freezes while typing or dragging--template 'Hangs'
Stutter while moving or animating--template 'Animation Hitches'
Memory growsfootprint <App>, leaks <App>, --template 'Allocations'
Fan, battery--template 'Energy Log', look for timers and polling

Read traces as text, not in the Instruments GUI: see "Measuring" in recipes.md. Delete every .trace after reading. A trace stores the app's full environment, and an app opened from an agent's shell inherits that shell's tokens. Never commit or share one.

  1. Fix with the matching recipe.
  2. Measure again with the same steps. Put before and after in the

commit message: "Picker opens in 40 ms, was 600 ms".

The rules that fix most problems

  • Main thread does UI only. File, network, database, image decoding,

Accessibility calls, and audio go elsewhere. A main-thread call that waits on another process (CoreAudio, AX) can freeze the app for minutes.

  • Show first, work after. Put the window or panel on screen in the same

frame as the key press, then load. Never make the UI wait for the work.

  • Let the GPU composite. Large images go in a CALayer once. Pointer

movement changes only small layers. Never redraw a full-screen picture per mouse event.

  • Decode at display size. ImageIO thumbnails, cached in NSCache.
  • Do not animate what must be fast. Search results and switchers

update in place.

  • No polling without a reason. Timers get a tolerance and stop when

nothing on screen needs them.

Apple silicon notes

  • Core Animation, Core Image (one shared CIContext), Vision, and

AVFoundation already run on the GPU or the Neural Engine. Hand them the work instead of looping over pixels in Swift.

  • Write Metal (MTKView, compute shaders) only when a measurement shows

Core Animation or Core Image is too slow. Most apps never need it.

  • Unified memory means a CGImage from ScreenCaptureKit passes to a layer

without a copy. Keep it as a CGImage or IOSurface. Converting to NSImage and back costs copies.

Done when the slow action has a measured before and after, the after meets the two numbers at the top, and the commit message names both.

同じリポジトリから

関連する Skills

すべての Skills