iOS-Trace: Autonome Anwendungs-Performance-Optimierung
iOS-Trace ist eine Closed-Loop-Engine zur Performance-Optimierung von iOS- und iPadOS-Anwendungen, die auf physischen iPhone-/iPad-Geräten und lokalen iOS-Simulatoren (SwiftUI, UIKit, Metal, CoreAudio/AVAudioEngine und URLSession-Netzwerk) ausgeführt werden.
Das Kernziel ist die Eliminierung der manuellen Instruments-GUI-Interaktion. Ein KI-Agent kann autonom diagnostizieren, Engpässe lokalisieren, Codeänderungen durchführen, mit differentialem Benchmarking nachtesten und iterieren, bis die Performance-Ziele mit empirischen Daten verifiziert sind.
+-------------------------------------------------------------------------+
| Der Autonome Optimierungszyklus |
| |
| 1. Zielabstimmung ──> 2. Diagnostisches Tracing ──> 3. Gezielter Code-Fix|
| ^ │ |
| │ ▼ |
| └────── Iteration, falls Ziel nicht erreicht <── 4. Nachtest |
+-------------------------------------------------------------------------+
Phase 1: Benutzer-Zielabstimmung (Pre-Flight-Fragebogen)
Bevor Code geändert oder Traces auf mobilen Geräten erfasst werden, muss sich der Agent mit dem Benutzer über Optimierungsziele und Erfolgskriterien abstimmen.
Modales Tool vs. Chat-Interaktion
- Wenn Ihre Agentenplattform ein interaktives Fragebogen-/modales Tool bereitstellt (z. B.
ask_question, Eingabedialoge oder auswählbare Optionenlisten), rufen Sie es auf, um dem Benutzer diese Auswahlmöglichkeiten sauber zu präsentieren. - Wenn kein modales Tool verfügbar ist, fragen Sie den Benutzer direkt im Chat mit strukturierten Optionen und konkreten empfohlenen Werten.
Fragen an den Benutzer
-
Primäres Optimierungsziel:
- Option A: Reduzierung der Batterieentladung, CPU-Auslastung und thermischen Drosselung.
- Option B: Senkung des Speicher-Fußabdrucks, transienter Allokationsspitzen oder Verhinderung von Jetsam-OOM-Abstürzen.
- Option C: Beseitigung von UI-Frame-Rucklern und verworfener Animationsframes (ProMotion 120Hz-Ruckler).
- Option D: Beschleunigung der mobilen App-Kaltstartzeit.
- Option E: Optimierung des Funknetz-Overheads und der Batch-Anforderungseffizienz.
-
Spezifische Performance-Ziele (mit empfohlenen Standardwerten) :
- Batterie- & CPU-Ziele:
- Leerlauf-Baseline-Ziel: < 15 M/s Anweisungen, CPU-Impakt < 0,3.
- Aktives Arbeitslast-Ziel: < 80 M/s Anweisungen (oder angeben: Reduktion um 30% - 50%).
- Speicher- & Jetsam-Ziele:
- Maximaler residenter RAM: Begrenzung auf < 150 MB (Standard-Utilities) oder < 300 MB (Medien-/reichhaltige interaktive Apps).
- Allokationsereignisrate: < 400 Ereignisse/s während stabiler Interaktion.
- Speicherlecks: Exakt 0 persistente Lecks.
- UI-Glätte & Bildwiederholraten-Ziele:
- Ruckelrate: < 5,0 ms/s (akzeptabel), < 1,0 ms/s (flüssig/ProMotion 120Hz-Niveau).
- Maximale Ruckeldauer: < 16,6 ms (60Hz) oder < 8,33 ms (120Hz).
- Startzeit-Ziele:
- Zeit bis zum ersten Frame: < 400 ms (hervorragend), < 800 ms (akzeptabel).
- Netzwerk- & Funkziele:
- Funk-Overhead: Bündeln Sie periodische Pings zu einzelnen Burst-Anfragen, um den Standby-Stromverbrauch des Funkmoduls zu vermeiden.
- Batterie- & CPU-Ziele:
-
Benchmark-Benutzerszenario:
- Fragen Sie den Benutzer, welcher spezifische Bildschirm, welche Benutzerinteraktion, welches physische Gerät oder welcher Simulator getestet werden soll.
Sobald die Ziele bestätigt sind, fahren Sie mit Phase 2 fort.
Umfang und Voraussetzungen
- Zielplattformen: iOS- und iPadOS-Anwendungen, die auf physischen iPhone-/iPad-Geräten (verbunden über USB oder lokales Netzwerk) oder lokalen iOS-Simulatoren ausgeführt werden. (Für macOS-Desktop-Anwendungen verwenden Sie macOS-Trace).
- Host-System: macOS 12+ auf Apple Silicon oder Intel Mac mit vollständigem Xcode oder Xcode-Command-Line-Tools (
xcode-select -p,xcrun xctrace version). - Gerätebereitschaft:
- Das physische iPhone/iPad muss entsperrt und vom Mac-Host vertrauenswürdig sein.
- Das Gerät muss unter
== Devices ==(nicht unter== Devices Offline ==) erscheinen, wennxcrun xctrace list devicesausgeführt wird. - Die Auto-Sperre sollte auf "Nie" gesetzt oder das Display während der Aufnahmen wach gehalten werden, um zu verhindern, dass iOS Hintergrundprozesse aussetzt.
- Python: Python 3.8+ auf dem Host-Mac (verwendet nur die Standardbibliothek; keine externen pip-Abhängigkeiten).
- Prozessberechtigungen: Debug-Builds oder entwicklerbereitgestellte Builds mit der Berechtigung
get-task-allowsind für--attach <PID>erforderlich.
Regeln für Agenten
Befolgen Sie diese nicht verhandelbaren Regeln während des automatisierten Profilings:
- Überprüfen Sie den Geräteverbindungsstatus: Führen Sie vor der Aufnahme immer
xcrun xctrace list devicesaus. Versuchen Sie niemals, eine Aufnahme gegen ein Gerät durchzuführen, das unter== Devices Offline ==aufgeführt ist. - Verhindern Sie Bildschirmsperre und Hintergrundlegung: Wenn das iOS-Gerät gesperrt wird oder zum Home-Bildschirm zurückkehrt, setzt iOS den Prozess aus oder drosselt ihn, was zu ungültigen Messungen führt. Halten Sie das Gerät wach und die App im Vordergrund.
- Erstellen Sie zuerst eine Baseline: Nehmen Sie niemals nur die aktive Arbeitslast auf. Erfassen Sie immer zuerst einen Leerlauf-Baseline-Durchlauf (App im Vordergrund, Gerätedisplay an, Arbeitslast pausiert), bevor Sie den aktiven Zustand aufzeichnen. Berechnen Sie:
Delta = Aktiv - Baseline. - Verwenden Sie gleiche Testparameter: Vergleichen Sie Durchläufe mit identischen Abtastdauern (Standard:
60s), identischen Gerätebatteriezuständen (vermeiden Sie Profiling bei unter 20% Batterie oder Energiesparmodus) und identischen Testeingabedaten. - Keine Python-Abhängigkeiten von Drittanbietern: Alle gebündelten Skripte (
scripts/compare_elements.py,scripts/parse_power.py,scripts/top_categories.py) verwenden nur die Python-3-Standardbibliothek. - Ausgaben in
/tmp/ios-traces/speichern: Speichern Sie alle.trace-Bündel und.xml-Exporte in/tmp/ios-traces/mit Zeitstempel- und szenariobezogenen Dateinamen. - Schützen Sie das Konversationskontextbudget: Trace-Dateien und rohe exportierte XML-Dokumente können zig oder hunderte Megabyte groß sein. Geben Sie niemals rohe
.trace-Ausgaben, vollständige Call-Trees oder ungeparstes Allocations-XML in den Konversationskontext des Agenten. Verwenden Sie immer die gebündelten Python-Skripte, um die Daten zu streamen, zu filtern, zu bewerten und zusammenzufassen, bevor Sie sie lesen. - Konzentrieren Sie sich auf primäre Engpässe: Streuen Sie keine Mikrooptimierungen über Dutzende von harmlosen Utility-Funktionen. Profilen Sie zuerst, um den dominanten Beitrag (z. B. redundante Oberflächeninstanzen, häufige Timer-Neuauswertungen, ungepufferte I/O) zu bestätigen und konzentrieren Sie Optimierungsbemühungen ausschließlich auf diese Grundursache.
- Ändern Sie niemals stillschweigend die UI, visuelle Effekte oder das Kernverhalten: Wenn ein Performance-Engpass die visuelle Wiedergabetreue (wie Unschärfe/Materialien, Frame-Animationen, Schatten, Layout-Übergänge) oder das wesentliche Softwareverhalten betrifft:
- Entfernen oder degradieren Sie die visuelle Funktion nicht einseitig.
- Fragen Sie den Benutzer formell um Erlaubnis (mit einer interaktiven Eingabeaufforderung oder einer expliziten Chat-Nachricht).
- Artikulieren Sie den Kompromiss klar: Beschreiben Sie die visuelle Änderung vorher und nachher, erklären Sie, warum die Funktion Ressourcen verbraucht, und präsentieren Sie den konkreten erwarteten Performance-Gewinn (z. B. "Das Deaktivieren von dynamischen Schatten und Unschärfe auf Kartenansichten wird den durchschnittlichen GPU-Impakt von 1,8 auf 0,2 reduzieren und 120Hz ProMotion-Ruckler beseitigen").
- Bereinigen Sie Aufnahme-Artefakte: Jede
xctrace-Aufnahme schreibt mehrere GB flüchtige Kernel-Traces (instruments*.ktrace) und einen Instruments-CLI-Cache (C/com.apple.dt.InstrumentsCLI) in den systemweiten Temp-Ordner des Benutzers ($TMPDIR).scripts/run_trace.shentfernt sie automatisch beim Beenden (sowohl bei Erfolg als auch bei Fehler). Wenn Siexctracedirekt ausführen, bereinigen Sie diese selbst, bevor Sie abschließen:Beenden Sie eine Sitzung niemals, ohne hunderte GB flüchtiger Aufnahmedaten zu hinterlassen.find "${TMPDIR:-/tmp}" -maxdepth 1 -type f -name 'instruments*.ktrace' -delete 2>/dev/null || true
Das 4-Phasen-Optimierungsprotokoll
Phase 2: Diagnostisches Profiling & Attribution
Bevor Sie Code schreiben, messen Sie den aktuellen Zustand auf dem Gerät und isolieren Sie die Grundursache:
# 1. Bestätigen Sie, dass das Zielgerät online und entsperrt ist (optionale Prüfung;
# run_trace.sh erkennt automatisch das erste verbundene iPhone/iPad, wenn --device weggelassen wird)
xcrun xctrace list devices
BUNDLE_ID="com.example.MyApp"
# SKILL_DIR = das installierte Verzeichnis dieser Fähigkeit (passen Sie es an, falls anders installiert)
SKILL_DIR="$HOME/.claude/skills/ios-trace"
# 2. 60s Leerlauf-Baseline aufzeichnen (Gerät entsperrt, App im Vordergrund, Arbeitslast pausiert)
"$SKILL_DIR/scripts/run_trace.sh" \
--bundle-id "$BUNDLE_ID" \
--template power \
--duration 60s \
--label "01-baseline"
# 3. Ziel-Arbeitslast in der App auslösen, aktiven Zustand aufzeichnen
"$SKILL_DIR/scripts/run_trace.sh" \
--process "MyApp" \
--template power \
--duration 60s \
--label "02-pre-opt"
# 4. Pre-Optimierungs-Delta berechnen
python3 "$SKILL_DIR/scripts/compare_elements.py" \
/tmp/ios-traces/01-baseline-power.xml:"Idle Baseline" \
/tmp/ios-traces/02-pre-opt-power.xml:"Active Pre-Opt"
Verwenden Sie die spezialisierten Templates, um den Engpass zu attribuieren:
- Führen Sie
--template timeaus, um heiße Call-Tree-Funktionen in Worker-Threads zu isolieren. - Führen Sie
--template allocmitscripts/top_categories.pyaus, um übermäßige Allokationen zu identifizieren, die Speicherdruck verursachen. - Führen Sie
--template hitcheswährend des Scrollens aus, um Render- vs. Commit-Verzögerungen auf ProMotion-Displays zu isolieren. - Führen Sie
--template networkaus, um kontinuierliche, ungebündelte Funk-Aufwachvorgänge zu erkennen.
Phase 3: Gezielte Code-Modifikation
Wenden Sie minimale, chirurgische Korrekturen basierend auf den Erkenntnissen an:
- Speicherspitzen & Jetsam: Verwenden Sie Downsampling für hochauflösende Bilder mit
CGImageSourceCreateThumbnailAtIndexanstattUIImagein voller Größe zu laden. - ProMotion-Ruckler: Entfernen Sie komplexe Schatten und Offscreen-Blending-Pässe; verlagern Sie schwere View-Layout-Berechnungen vom Haupt-Thread.
- Funkenergie-Overhead: Bündeln Sie periodische Netzwerkanfragen in einheitliche Payload-Bursts, um den Standby-Stromverbrauch des Funkmoduls zu eliminieren.
- Echtzeit-Audio: Stellen Sie sicher, dass keine Heap-Allokationen in CoreAudio-Render-Callbacks (
AVAudioEngineoder RemoteIO) stattfinden.
Erstellen Sie die Anwendung neu und stellen Sie sie auf dem Gerät bereit.
Phase 4: Nachtest, quantitative Überprüfung & Entscheidungstor
Führen Sie das Profil unter identischen Bedingungen erneut aus und bewerten Sie das Delta:
# 1. Post-Optimierungs-Arbeitslast aufzeichnen
"$SKILL_DIR/scripts/run_trace.sh" \
--process "MyApp" \
--template power \
--duration 60s \
--label "03-post-opt"
# 2. Pre-Opt vs. Post-Opt gegen Baseline vergleichen
python3 "$SKILL_DIR/scripts/compare_elements.py" \
/tmp/ios-traces/01-baseline-power.xml:"Idle Baseline" \
/tmp/ios-traces/02-pre-opt-power.xml:"Active Pre-Opt" \
/tmp/ios-traces/03-post-opt-power.xml:"Active Post-Opt"
Beispiel einer Entscheidungsausgabe:
Scenario Sec CPU Avg CPU Max Display GPU Avg Total Instr Instr M/s WiFi Tx/Rx
=========================================================================================================
Idle Baseline 60 0.12 0.60 0.05 0.00 0.85G 14.2 0.0/0.0MB
Active Pre-Opt 60 2.40 4.80 1.10 1.80 15.60G 260.0 14.2/1.8MB
Active Post-Opt 60 0.55 1.10 0.15 0.20 4.20G 70.0 2.1/0.4MB
---------------------------------------------------------------------------------------------------------
Differential vs Baseline [Idle Baseline]:
Active Pre-Opt +245.8 M/s Anweisungen, CPU Avg Delta +2.28, WiFi Tx Delta +14.20MB
Active Post-Opt +55.8 M/s Anweisungen, CPU Avg Delta +0.43, WiFi Tx Delta +2.10MB
Optimierungs-Delta (Post-Opt vs Pre-Opt):
Anweisungsdurchsatz: -73.1% (70.0 vs 260.0 M/s)
Durchschnittlicher CPU-Impakt: -77.1% (0.55 vs 2.40)
Durchschnittlicher GPU-Impakt: -88.9% (0.20 vs 1.80)
WLAN-Funkverkehr: -85.2% (2.1MB vs 14.2MB)
Entscheidungstor-Logik:
- Ziel erreicht: Präsentieren Sie dem Benutzer die empirische Vergleichstabelle und schließen Sie ab.
- Ziel nicht erreicht: Behalten Sie die vorherige Optimierung bei, isolieren Sie den nächsten verbleibenden Hotspot und wiederholen Sie Phase 3 und Phase 4.
Bereinigung nach dem Bericht: Nachdem der Benutzer den endgültigen Optimierungsbericht akzeptiert hat, löschen Sie die angesammelten .trace-Bündel unter /tmp/ios-traces/ (jedes kann zig GB groß sein), es sei denn, der Benutzer bittet ausdrücklich darum, sie zu behalten. Die im Bericht gezeigte endgültige Vergleichstabelle und die .xml-Exporte sind ausreichende Nachweise.
Direkte CLI-Befehle
Wenn Sie xctrace direkt ohne run_trace.sh ausführen:
Aufzeichnen
# An laufende App auf dem Gerät anhängen
xcrun xctrace record \
--device <DEVICE_UDID> \
--template 'Power Profiler' \
--time-limit 60s \
--output /tmp/ios-traces/power.trace \
--attach <PID>
# App auf dem Gerät kalt starten
xcrun xctrace record \
--device <DEVICE_UDID> \
--template 'Time Profiler' \
--time-limit 30s \
--output /tmp/ios-traces/launch.trace \
--launch -- com.example.MyApp <LaunchArgs>
Exportieren
# Power Impact-Tabelle exportieren (CPU-Anweisungen, Energie, GPU, Display, WiFi/Cellular)
xcrun xctrace export \
--input /tmp/ios-traces/power.trace \
--xpath "/trace-toc/run[@number='1']/data/table[@schema='ProcessSubsystemPowerImpact']" \
> /tmp/ios-traces/power.xml
# Allocations-Zusammenfassungstabelle exportieren
xcrun xctrace export \
--input /tmp/ios-traces/alloc.trace \
--xpath "/trace-toc/run[@number='1']/data/table[@schema='all-allocations-summary']" \
> /tmp/ios-traces/alloc.xml
Template-Referenz
Instruments-Templates, die unter iOS über scripts/run_trace.sh und headless xctrace unterstützt werden:
Rechnen, Batterie & Energie
| Template | Kurzname | Zielmetriken & Export-Schema | Anwendungsfall |
|---|---|---|---|
Power Profiler | power | Anweisungen/s (M/s), CPU/GPU/Display/WiFi/Cellular Energie-Impacts (ProcessSubsystemPowerImpact). | Umfassende Batterieentladung, thermische Drosselung und A/B-Benchmarking. |
Time Profiler | time | CPU-Sample-Gewichte nach Thread, Call-Tree-Hotspots, Haupt-Thread-Blockierungsmethoden. | Hohe CPU-Auslastung, außer Kontrolle geratene Worker-Threads und heiße Funktionspfade. |
CPU Counters | c |
...
[abgeschnitten für Übersetzung]