메뉴바 픽셀 펫이 CPU 31%를 먹던 이유와 0.3%로 줄인 과정
메뉴바에서 우공 할아버지가 삽질하는 Token Yugong을 만들고 있습니다. 애니메이션을 빠르게 돌려 두고 top으로 재 보니 v0.2.4가 CPU를 60초 평균 31.28% 쓰고 있었습니다(M5 Pro). 픽셀 몇 개 움직이는 앱치고는 너무 많아서 세 단계로 줄였습니다.
1. 프레임마다 메뉴바 레이아웃이 다시 돌았다 (31.28% → 2.78%)
스프라이트 이미지를 바꿀 때마다 메뉴바 레이아웃이 다시 돌았습니다. 상태 항목 폭을 고정해 그림만 바뀌어도 재배치가 일어나지 않게 하고, 닫혀 있는 SwiftUI 녹화 화면에는 값을 보내지 않게 했습니다. 같은 방법으로 재니 2.78%였습니다(PR #28).
2. 폭을 고정해도 이미지 셀이 매번 무효화됐다 (4.78% → 0.43%)
설치된 v0.2.5를 다시 재니 4.78%였습니다. 폭이 고정돼도 NSStatusBarButton.setImage가 프레임마다 버튼의 이미지 셀을 무효화했습니다. 버튼은 클릭용으로만 두고, 캐시한 스프라이트와 글자는 Core Animation 하위 레이어로 옮겼습니다. 이제 한 프레임에 바뀌는 것은 CALayer.contents 하나뿐이고 0.43%로 내려갔습니다(PR #30).
3. 가만히 있을 때도 20초마다 파일을 다 읽었다 (평균 1.45% → 0.015%)
저전력 모드에서 그림이 멈춰 있어도 20초마다 사용량 파일 전체를 다시 읽고 있었습니다. 그때마다 1초쯤 CPU가 29%까지 튀었고 평균은 1.45%였습니다. 이제 브리지와 사용량 디렉터리를 감시하다가 바뀌었을 때만 읽고, 그것도 30초에 한 번으로 묶었습니다. 20초 폴링은 5분짜리 복구 확인으로 바꿨습니다. 정지 상태 60초 평균은 0.015%, 빠른 애니메이션 상태는 0.313%입니다(PR #31).
배운 것
- 메뉴바 앱은 "그리는 비용"보다 "AppKit이 다시 배치하는 비용"이 큽니다. 폭을 고정하고 레이어 내용만 바꾸면 대부분 사라집니다.
- macOS는
NSStatusItem하나의 이미지를 모든 메뉴바에 복제해 그립니다. 지금 보이는 화면 것만 움직이게 할 방법은 없어서, 캐시한 그림 하나를 쓰고 가려졌을 때는 아예 그리지 않게 했습니다. - 숫자는 모두 같은 Mac에서
top -l 60 -s 1로 잰 60초 평균입니다.
이 변경은 v0.2.7까지 들어갔고, v0.2.9에는 실험용 Linux 베타(AppImage, .deb)도 함께 올렸습니다. Claude Code, Codex 같은 AI 코딩 도구로 만들었습니다.
Claude Code·Codex 사용 한도를 지게와 산으로 보여 주는 픽셀 우공 메뉴바 앱
댓글
로그인 후 댓글을 남길 수 있습니다.
아직 댓글이 없습니다.