【免费下载链接】Skills
Agent skills for designers and builders using Codex, Claude, Cursor, and other AI coding agents
本文围绕仓库
agent-skills/codex/performance-profiling目录下的技能文档与演示工程展开,系统讲解 Apple 平台应用性能剖析的完整工作流:从决策树选型、Instruments 时间/内存/启动/能耗四类剖析、Xcode 诊断开关,到 MetricKit 生产监控与上线前审查清单,并落地为一套「证据优先」的可复现演示方案(demo/PROMPT.md 定义的输入—输出交接模式)。读完本文,你将掌握一套可直接套用的性能问题排查方法论,以及如何把该技能快速适配到 Codex、Claude、Cursor 等 AI 编码 Agent 的提示词上下文中。
该技能在仓库中的完整定义位于 SKILL.md,配套的演示提示词文档为 demo/PROMPT.md,四个领域参考文件分别覆盖时间剖析、内存剖析、启动优化与能耗诊断。
技能概览:一套按问题域驱动的性能排查体系
performance-profiling技能的定位非常明确:Guide performance profiling for Apple platform apps with Instruments, Xcode diagnostics, and MetricKit。它适用于以下典型场景(摘自 SKILL.md 的能力描述):
- 应用挂起(hangs)、卡顿(stutters)、掉帧(dropped frames)
- 高 CPU 占用、内存泄漏、内存持续增长、OOM 崩溃
- 冷启动/热启动/恢复过慢、首帧时间过长
- 电池消耗、热节流(thermal throttling)、后台能耗、网络浪费
- App Store 上架前的性能就绪度检查,以及为关键路径添加
os_signpost与测量钩子
技能的核心方法论是「先选型、再剖析、后最小修复、用真实测量验证」。这与演示文档中强调的 evidence-first(证据优先)理念一脉相承:任何性能论断都必须有可复现的剖析数据支撑。
决策树:改代码之前先选对参考文档
SKILL.md 提供了一个明确的决策树,要求在修改代码之前先确定性能问题的归属类别,再读取对应的参考文件:
What performance problem are you investigating? + App hangs, stutters, dropped frames, slow UI, high CPU -> Read references/time-profiler.md + High memory, leaks, OOM crashes, growing footprint -> Read references/memory-profiling.md + Slow cold launch, warm launch, resume, or time to first frame -> Read references/launch-optimization.md + Battery drain, thermal throttling, background energy, network waste -> Read references/energy-diagnostics.md + General "app feels slow" -> Start with references/time-profiler.md, then references/memory-profiling.md + Pre-release performance audit -> Read all reference files and use the review checklist below对应仓库中的四个参考文件:
- references/time-profiler.md:CPU 剖析、挂起检测、signpost API
- references/memory-profiling.md:Allocations、Leaks、Memory Graph 调试器
- references/launch-optimization.md:启动阶段与冷/热启动优化
- references/energy-diagnostics.md:电池、热状态与网络效率
问题—工具—指标速查表
| 问题 | 工具 | 关键指标 | 参考文件 |
|---|---|---|---|
| 超过 250ms 的 UI 挂起 | Time Profiler + Hangs | 挂起时长、主线程堆栈 | references/time-profiler.md |
| 高 CPU 占用 | Time Profiler | 按函数统计的 CPU 百分比、调用树权重 | references/time-profiler.md |
| 内存泄漏 | Leaks + Memory Graph | 泄漏字节、保留环路径 | references/memory-profiling.md |
| 内存增长 | Allocations | Live Bytes、代(generation)分析 | references/memory-profiling.md |
| 启动缓慢 | App Launch | 首帧时间、pre-main、post-main | references/launch-optimization.md |
| 电池消耗 | Energy Log | Energy Impact、CPU/GPU/网络活动 | references/energy-diagnostics.md |
| 热问题 | Activity Monitor、Instruments | 热状态迁移 | references/energy-diagnostics.md |
| 网络浪费 | Network profiler | 冗余请求、payload 大小 | references/energy-diagnostics.md |
六步工作流:从症状到验证的完整闭环
SKILL.md 规定了一套标准工作流,这也是演示文档中「输入—输出交接」的核心骨架:
- 从用户报告、traces、日志或代码路径中识别性能类别;
- 除非问题宽泛或不明朗,否则只读取匹配的参考文件;
- 优先使用Release 构建 + 真机 + 有代表性的数据进行剖析;
- 在提出修复方案前,先检查剖析结果点名的代码路径;
- 实施针对已测量瓶颈的最小修复;
- 重新剖析或添加可重复测量,确认改进真实生效。
剖析的黄金守则
- 尽量在真机上剖析:模拟器(Simulator)使用的是宿主机的 CPU 与内存,结论不可直接外推;
- 使用 Release 配置:Debug 构建关闭编译器优化,热路径可能完全不同;
- 用代表性数据复现:空数据库或玩具资源无法暴露真实瓶颈(10 个 item 与 10,000 个 item 暴露的是不同的问题);
- 关闭无关 App以减少剖析噪声;
- 修复前后都保留测量数据,让结论可量化;
- 当某个工作流需要持续计时可见性时,添加
os_signpost标记。
时间剖析:Time Profiler 与挂起检测
参考 references/time-profiler.md 展开。
Instruments 基本操作
- Xcode > Product > Profile(快捷键
Cmd+I)——自动以 Release 构建并打开 Instruments; - 选择Time Profiler模板;
- 点击录制,复现慢操作,停止录制。
关键设置:
- Recording Mode = Deferred:开销更低,适合接近生产环境的剖析;
- High Frequency = 10ms 采样:用于细粒度分析(默认 1ms);
- Record Waiting Threads:开启后可看到阻塞在锁/IO 上的线程。
阅读 Time Profiler 结果
调用树(Call Tree)中的三个核心字段:
- Weight:函数自身 + 所有子节点花费的总时间;
- Self Weight:仅该函数自身花费的时间(不含子节点);
- Symbol Name:被采样的函数/方法。
常用过滤器:
| 过滤器 | 用途 |
|---|---|
| Separate by Thread | 隔离主线程与后台线程 |
| Invert Call Tree | 叶子函数优先显示(时间真正花在哪) |
| Hide System Libraries | 聚焦自己的代码 |
| Flatten Recursion | 将递归调用折叠为一条 |
推荐阅读路径:Separate by Thread找到 Main Thread →Invert Call Tree让最重的叶子函数置顶 →Hide System Libraries聚焦自有函数 → 展开节点回溯调用链 → 双击函数跳转源码。
什么算一次挂起(Hang)
| 时长 | 分类 | 用户感知 |
|---|---|---|
| < 100ms | 可接受 | 流畅 |
| 100–250ms | 微挂起 | 轻微卡顿 |
| 250ms–1s | 挂起 | 明显延迟 |
| > 1s | 严重挂起 | App 像坏了一样 |
| > 3s | Watchdog 击杀风险 | 系统可能终止进程 |
挂起检测实操:Time Profiler 模板自带 Hang detection 车道,或单独使用Animation Hitchesinstrument 针对 UI 卡顿;录制并复现交互后,Hangs 车道中的橙色/红色区域即挂起时长,点击挂起可查看当时的主线程调用栈。
典型主线程挂起根因与最小修复
参考文件给出了五类最常见的「坏—好」对照代码:
1. 主线程同步文件 IO
// Bad - blocks main thread func loadData() -> Data { return try! Data(contentsOf: largeFileURL) } // Good - move to background func loadData() async -> Data { return try! await Task.detached { try Data(contentsOf: largeFileURL) }.value }2. 主线程同步网络调用——Data(contentsOf: remoteURL)会阻塞主线程等待结果,应改用URLSession的async/await接口try await URLSession.shared.data(from:)。
3. 主线程重计算——大数组sorted/filter应放入Task.detached后回主线程刷新 UI。
4. 主线程 Core Data / SwiftData 大批量 fetch——在后台ModelContext中执行 fetch。
5. 主线程图片解码——UIImage(contentsOfFile:)的懒解码会阻塞首次展示;iOS 15+ 使用byPreparingThumbnail(ofSize:)或byPreparingForDisplay()异步解码:
let thumbnail = await UIImage(contentsOfFile: path)? .byPreparingThumbnail(ofSize: targetSize) imageView.image = thumbnailos_signpost:为自定义剖析打点
当某个工作流需要持续计时可见性时,用os_signpost标记区间与事件:
import os extension OSSignpostID { static let dataLoad = OSSignpostID(log: .performance) } extension OSLog { static let performance = OSLog( subsystem: Bundle.main.bundleIdentifier!, category: "Performance" ) } // Mark intervals func loadData() async throws -> [Item] { let signpostID = OSSignpostID(log: .performance) os_signpost(.begin, log: .performance, name: "DataLoad", signpostID: signpostID) defer { os_signpost(.end, log: .performance, name: "DataLoad", signpostID: signpostID) } // ... actual work return items } // Mark events (single point) os_signpost(.event, log: .performance, name: "CacheMiss")在 Instruments 中:添加os_signpostinstrument → 按 subsystem/category 过滤找到自己的标记 → 区间显示为带时长的横条、事件显示为点。
Thread Performance Checker
在Scheme > Run > Diagnostics > Thread Performance Checker开启后,运行时检测三类问题并以紫色运行时警告呈现在 Xcode Issue Navigator:
- 优先级反转:高优先级线程等待低优先级线程;
- 主线程上的非 UI 工作:主线程上的磁盘 IO、网络调用;
- 过度创建线程。
内存剖析:Allocations、Leaks 与 Memory Graph
参考 references/memory-profiling.md 展开。
Allocations Instrument 关键指标
| 指标 | 含义 |
|---|---|
| All Heap Allocations | 堆上分配的总内存 |
| Live Bytes | 当前存活(未释放)的内存 |
| Transient Bytes | 录制期间分配又释放的内存 |
| # Living | 存活分配对象数 |
| # Transient | 已释放分配数 |
阅读技巧:按Live Bytes排序找最大内存消耗者;按# Living排序找数量最多的分配;Persistent列显示跨代存活的对象。点击分类可查看带调用栈的单个分配。
代分析(Generation Analysis):定位内存增长的杀手锏
- 开始录制;
- 点击Mark Generation建立基线;
- 执行一次操作(打开页面、加载数据等);
- 再次Mark Generation;
- 重复相同操作;
- 对比各代——相同操作之间的增长 = 泄漏或无限缓存。
判断标准:
- 稳定:每代 Live Bytes 相近;
- 泄漏:每代都在增长,前代对象持续存活;
- 缓存:增长在几代后趋于平稳(可能是设计使然)。
常见内存问题与最小修复
无限增长的缓存——用NSCache替代普通字典以获得自动淘汰机制:
class ImageCache { private let cache = NSCache<NSURL, UIImage>() init() { cache.countLimit = 100 cache.totalCostLimit = 50 * 1024 * 1024 // 50 MB } func store(_ image: UIImage, for url: URL) { let cost = image.cgImage.map { $0.bytesPerRow * $0.height } ?? 0 cache.setObject(image, forKey: url as NSURL, cost: cost) } }大图未降采样——4032x3024 的照片在内存中约占 48MB;应使用CGImageSourceCreateThumbnailAtIndex配合kCGImageSourceThumbnailMaxPixelSize生成显示尺寸的缩略图,同时开启kCGImageSourceShouldCacheImmediately与kCGImageSourceCreateThumbnailWithTransform。
保留环(Retain Cycle)四大经典模式
Leaks 检测的是不可达内存(堆上无根引用的对象),无法检测「逻辑泄漏」(可达但永不使用,如无限缓存),因此保留环排查要主动做。四个典型模式及修复:
- 闭包强捕获 self:
Timer.scheduledTimer的闭包里self.refresh()构成self → timer → closure → self环,改为[weak self]; - delegate 强引用:
Service的var delegate: ServiceDelegate?需改为weak var delegate; - 集合中的闭包:
handlers.append { self.handleEvent() }中每个闭包都强持有 self,逐个加[weak self]; - NotificationCenter block API:token 会持有闭包,闭包持有 self,需
[weak self]。
Xcode Memory Graph Debugger
适用场景:Leaks 报泄漏但需要看谁在持有对象、怀疑保留环但代码审查找不到、需要完整所有权图。
用法:
- 以Debug模式运行 App(非 Profile);
- 复现对象本应释放的状态;
- 点击调试栏的Memory Graph按钮,Xcode 暂停并捕获堆;
- 左侧栏按类型列出存活对象,紫色感叹号是 Xcode 检测到的泄漏/保留环,中央画布是引用图,点击对象可见其强引用来源与分配回溯。
配合Malloc Stack Logging(Scheme > Run > Diagnostics 开启,Live Allocations Only)可获得完整分配调用栈。排查技巧:按模块名过滤忽略系统对象、寻找互相指向的环、用File > Export Memory Graph导出共享。
autoreleasepool:紧循环中的内存尖峰
处理大型集合(1000+ 项)、循环中创建临时NSString/NSData/NSNumber、图像处理管线时,autoreleased对象会累积到循环结束才排空,造成内存尖峰;用autoreleasepool {}包住每次迭代即可保持内存平稳。纯 Swift 值类型(String、Data、Array)无需此优化。
代码内跟踪内存占用
import os func logMemoryFootprint() { var info = mach_task_basic_info() var count = mach_msg_type_number_t( MemoryLayout<mach_task_basic_info>.size / MemoryLayout<natural_t>.size ) let result = withUnsafeMutablePointer(to: &info) { $0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count) } } if result == KERN_SUCCESS { let usedMB = Double(info.resident_size) / 1_048_576 os_log("Memory footprint: %.1f MB", usedMB) } }启动优化:App Launch 剖析与 pre/post-main
参考 references/launch-optimization.md 展开。
启动阶段与目标预算
冷启动时间线分为两段:pre-main(DYLD 加载 dylibs、rebase/bind、+load与静态初始化、ObjC 运行时初始化)与post-main(App init、UIKit/SwiftUI 场景搭建、根视图布局渲染),以首帧渲染为启动完成标志。
| 启动类型 | 良好 | 可接受 | 较差 |
|---|---|---|---|
| 冷启动 | < 400ms | < 1s | > 2s |
| 热启动 | < 200ms | < 500ms | > 1s |
| 恢复(Resume) | < 100ms | < 200ms | > 500ms |
- 冷启动:App 不在内存中,需要完整 DYLD 加载、运行时初始化、UI 搭建;
- 热启动:App 刚被终止但系统缓存了部分数据;
- 恢复:App 之前被挂起到后台。
App Launch Instrument
Product > Profile(Cmd+I)→ 选App Launch模板 → 录制(App 自动启动)→ 完全可交互后停止。重点看三个测量:
- Time to first frame:进程启动到首次 CA commit 的总时长;
- Pre-main time:进程启动到
main()/@main入口; - Post-main time:
main()到首帧渲染。
Pre-main 优化要点
- 减少动态框架:每个动态框架约增加 10–30ms 启动耗时(15 个动态框架 ≈ 300ms DYLD 加载,3 个 ≈ 50ms)。优先转静态库、使用默认静态的 Swift Package Manager、合并小框架,用
otool -L YourApp.app/YourApp检查链接的 dylib; - 移除静态初始化器:ObjC
+load、C 风格@_cdeclconstructor 都在main()之前执行,改为首次使用时惰性初始化(static let shared); - 精简 ObjC 元数据:大型 ObjC 类层级、大量 category 会增加 rebase/bind 时间,Swift 非
@objc类更高效。
Post-main 优化要点
延迟非必要初始化——@main App的init()里只保留真正必须立即启动的部分(如崩溃上报),Analytics、Remote Config、缓存预热全部挪到首帧之后的.task { }中:
@main struct MyApp: App { init() { // Only crash reporter is truly needed immediately CrashReporter.shared.start() } var body: some Scene { WindowGroup { ContentView() .task { // Defer everything else to after first frame await deferredSetup() } } } }惰性视图加载:NavigationStack本身惰性加载目的地视图;自定义容器优先LazyVStack而非VStack;首屏先渲染轻量 skeleton/placeholder,数据用.task {}异步加载;数据库迁移放到后台并显示迁移进度 UI。
代码内测量启动时长
os_signpost版本:在App.init()里.begin,在ContentView.onAppear里.end,Instruments 中即可看到 AppLaunch 区间;快速粗测版本用CFAbsoluteTimeGetCurrent()打印启动耗时。
能耗诊断:Energy Log、热状态与生产级能耗数据
参考 references/energy-diagnostics.md 展开。
为什么能耗值得单独一条赛道
- 电池消耗是用户删除 App 的首要原因;
- 过高能耗会触发App Store 审核标记;
- iOS 会对高能耗 App 在后台进行节流;
- 热节流(thermal throttling)会连累同设备上的所有 App。
Energy Impact 评分与组件构成
Energy Log 模板(iOS)或 Activity Monitor 模板(macOS),必须在物理设备上录制(能耗剖析依赖真实硬件)。
| 级别 | 评分 | 含义 |
|---|---|---|
| Low | 0–3 | 良好,电池消耗极小 |
| Medium | 3–8 | 活跃使用可接受,闲置不可接受 |
| High | 8+ | 需要调查,显著消耗 |
| Overhead | 红色条 | 你的 App 触发的系统开销 |
组件分解:CPU(最大能耗源)、GPU(渲染、Metal、动画)、Network(蜂窝最贵)、Location(GPS/Wi-Fi/基站测距)、Display(间接)、Overhead(触发的系统服务)。
常见能耗泄漏与修复
1. 过度轮询的 Timer——1 秒重复的Timer即使空闲也持续唤醒 CPU。修复:设置timer.tolerance = 0.5让系统合并唤醒;更优方案是用NotificationCenter的系统通知(如.significantTimeChange)替代轮询。
2. 过度精度的定位——天气/城市级功能用kCLLocationAccuracyKilometer+requestLocation()(单次,不连续);导航用kCLLocationAccuracyBestForNavigation+activityType = .automotiveNavigation+pausesLocationUpdatesAutomatically = true;「附近」功能用kCLLocationAccuracyHundredMeters+distanceFilter = 100。
3. 网络请求不聚合——4 个独立请求 = 4 次无线电激活;用async let并行组或单个 batch endpoint 让无线电一次突发完成;NWPathMonitor感知蜂窝/ Wi-Fi 差异(蜂窝下降低图片质量、关闭预取、延长埋点上报间隔)。
4. 后台任务滥用——不要在applicationDidEnterBackground里做长任务,应使用BGTaskScheduler提交可延后执行的BGProcessingTaskRequest(requiresNetworkConnectivity、requiresExternalPower按需设置),并实现expirationHandler取消未完成任务。
5. 不可见的持续动画——repeatForever动画应监听scenePhase,仅在.active时运行。
热状态监控
监听ProcessInfo.thermalStateDidChangeNotification,按状态分级降级:
| 状态 | 应对策略 |
|---|---|
.nominal | 全性能运行 |
.fair | 略热,停掉可选预加载 |
.serious | 高温,减少动画、降低图片质量、暂停后台同步 |
.critical | 节流临界,停掉一切非必要工作,必要时提示用户 |
MetricKit 生产能耗数据
MXMetricPayload中可读取:cpuMetrics(累计 CPU 时间与指令数)、gpuMetrics、cellularConditionMetrics、networkTransferMetrics(Wi-Fi/蜂窝上下行)、locationActivityMetrics(各精度档位累计时长)。
Xcode Energy Organizer
Xcode > Window > Organizer > Energy查看真实用户(TestFlight/App Store)的能耗报告,按 CPU、Location、Display、Network、GPU、Accessories 分解,可按版本过滤追踪回归,并单独展示后台能耗——这对电池投诉至关重要。
MetricKit 生产监控钩子:让性能测量持续在线
SKILL.md 给出了一套可直接落地的MXMetricManagerSubscriber实现,把启动、响应性、内存、挂起诊断全部接入统一上报:
import MetricKit final class PerformanceReporter: NSObject, MXMetricManagerSubscriber { func startCollecting() { MXMetricManager.shared.add(self) } func didReceive(_ payloads: [MXMetricPayload]) { for payload in payloads { if let launch = payload.applicationLaunchMetrics { log("Resume time: \(launch.histogrammedResumeTime)") } if let responsiveness = payload.applicationResponsivenessMetrics { log("Hang time: \(responsiveness.histogrammedApplicationHangTime)") } if let memory = payload.memoryMetrics { log("Peak memory: \(memory.peakMemoryUsage)") } } } func didReceive(_ payloads: [MXDiagnosticPayload]) { for payload in payloads { if let hangs = payload.hangDiagnostics { for hang in hangs { log("Hang: \(hang.callStackTree)") } } } } }MetricKit 的定位是生产环境的补充测量:Instruments 解决「能不能复现与定位」,MetricKit 解决「真实用户群体中的分布与回归」。启动直方图(histogrammedTimeToFirstDraw、histogrammedResumeTime)可以按桶枚举分布,用于判断线上启动时间是否稳定或恶化。
Xcode 诊断开关速查
在Scheme > Run > Diagnostics中按疑似问题匹配开启:
| 设置 | 用途 |
|---|---|
| Main Thread Checker | 主线程外的 UI 操作 |
| Thread Sanitizer | 数据竞争与不安全的共享状态 |
| Address Sanitizer | 缓冲区溢出与 use-after-free |
| Malloc Stack Logging | 分配调用栈 |
| Zombie Objects | 向已释放对象发消息 |
上线前审查清单(Review Checklist)
SKILL.md 将审查清单分为四个维度,可作为性能审计的最终验收标准:
响应性:
- 主线程无超过 100ms 的同步工作;
- 主线程无文件 IO 或网络调用;
- 大型 Core Data / SwiftData 查询使用后台 context;
- 图片解码在后台线程;
@MainActor只限真正需要 UI 访问的代码。
内存:
- delegate、闭包、观察者、async 任务中无保留环;
- 大资源不可见即释放;
- 集合与缓存有界;
- 创建 Objective-C 对象的紧循环使用
autoreleasepool。
启动:
@main App的init()无重活;- 非必要初始化已延迟;
- 动态框架在可行处最小化;
- 启动期间无同步网络调用。
能耗:
- 后台任务使用合适的
BGTaskScheduler请求类型; - 定位精度匹配产品需求;
- Timer 使用 tolerance 让系统合并唤醒;
- 网络请求尽量批处理并做缓存。
演示落地:从「症状」到「验证」的证据优先交接
agent-skills/codex/performance-profiling/demo/PROMPT.md 是这份技能的演示提示词文档,它把上面的方法论压缩成一个「输入 → 输出」的交接演示。文档定义了三种提示词形态:
Minimal prompt(最小提示词)
Use $performance-profiling to create a polished standalone HTML example that clearly demonstrates the skill.Recreate the demo(重建演示)
Use $performance-profiling to build a responsive reference demo for this capability: > Guide performance profiling for Apple platform apps with Instruments, Xcode diagnostics, and MetricKit. Use when investigating app hangs, stutters, high CPU, memory leaks, memory growth, OOM crashes, slow launch, battery drain, thermal issues, App Store performance readiness, or when adding os_signpost and measurement hooks.方向要求:将工作流呈现为紧凑的 evidence-first 输入与输出交接(input and output handoff);采用艺术化构图,一个清晰的视觉焦点、克制的辅助文案、足够的环境界面展示该技术在真实产品/落地页中的表现。
交付物约束(Deliverable)
- 生成
demo/index.html作为独立文档; - CSS 与 JavaScript 全部内联;
- 图片、字体、模型、纹理或第三方文件放入
demo/assets/; - 不得引入框架、包管理器、构建步骤或
node_modules; - 仅当控件有助于检查或回放技术时添加控件。
验收检查(Acceptance checks)
- 在390px 到 1440px区间保持响应式;
- 使用语义化 HTML、可见的焦点状态、处理
prefers-reduced-motion; - 所有 HTML/CSS/JS 都在
demo/index.html内; - 仅使用相对路径的本地资源;
- 展示真实感的输入与预期输出,但不得暴露真实客户或账户数据;
- 明确标注授权边界与验证状态(make authorization boundaries and verification status explicit)。
Remix prompt(混排/变体)
Use $performance-profiling and keep the same implementation contract, but change the subject, copy, palette, and content hierarchy. Preserve the core technique, accessibility behavior, responsive rules, and performance constraints demonstrated by the reference.注意这里的关键约束:变体可以改主题、文案、配色与内容层级,但必须保留参考实现的核心技术、无障碍行为、响应式规则与性能约束——这确保了每个 Remix 仍然是同一技能的合格演示。
演示内容拆解:一个典型的内存泄漏场景
仓库中 demo/input.md 与 demo/expected-output.md 是演示的虚构素材,恰好对应技能中的「内存 + 响应性」双问题域:
输入(症状):
The timeline starts smoothly, then drops frames after editing for 8–10 minutes. Memory grows continuously and does not fall after closing the editor.预期输出(剖析计划):
1. Record a reproducible signposted editing session. 2. Capture Time Profiler and Allocations traces. 3. Compare live-object growth before and after closing the editor. 4. Inspect retain cycles with Memory Graph. 5. Re-run the same scenario after the narrow fix.这份「症状 → 计划」的交接完美体现了技能的方法论闭环:
- 可复现:先录制带 signpost 的可复现编辑会话(对应「用代表性数据复现」+ os_signpost 守则);
- 双工具取证:Time Profiler 抓掉帧、Allocations 抓内存增长(对应决策树中「General slow → time-profiler → memory-profiling」路径);
- 代对比:对比关闭编辑器前后 live-object 增长,锁定「内存不回落」的证据(对应 Generation Analysis);
- 定位根因:用 Memory Graph 检查保留环——这正是演示场景中最可能的根因(编辑会话对象被某处强引用);
- 闭环验证:最小修复后重跑同一场景,确认改进真实生效。
实际演示产物 demo/index.html 将以上输入与输出并排呈现在暗色工作流卡片中,并完整遵守了 PROMPT.md 的契约:单文件、CSS/JS 内联、无外部依赖、390px 起响应式、语义化 HTML、显式标注「Portable fictional example. No live account or customer data.」——即验收检查中要求的授权边界与虚构性说明。
如何把该技能接入你的 AI 编码 Agent
仓库中 agents/openai.yaml 展示了技能在 Agent 侧的注册形态:
interface: display_name: "Performance Profiling" short_description: "Profile Apple app performance issues" default_prompt: "Use $performance-profiling to diagnose a slow or memory-heavy Apple app."在 Codex、Claude、Cursor 等支持 skill/agent 定义的编码工具中,可将技能目录(SKILL.md + references/ + demo/)挂载为可调用技能,然后用类似这样的提示词触发:
- 症状驱动:
Use $performance-profiling to diagnose an app that drops frames after a few minutes of editing. - 审计驱动:
Use $performance-profiling to run a pre-release performance audit. - 演示驱动:
Use $performance-profiling to create a polished standalone HTML example that clearly demonstrates the skill.
技能会自动按照决策树选择参考文件、按六步工作流输出「症状 → 剖析计划 → 最小修复 → 复测验证」的完整方案,这正是 evidence-first 交接模式的工程化价值:AI 产出的是有测量依据、可验证的改动,而不是凭感觉的猜测。
小结
performance-profiling技能的核心价值在于把 Apple 平台性能优化这件容易发散的事,收敛成一条「分类 → 选文档 → 取证 → 最小修复 → 复测」的确定性流水线:Time Profiler 管响应性与 CPU,Allocations/Leaks/Memory Graph 管内存,App Launch 管启动,Energy Log 与热状态管能耗,MetricKit 把测量延伸到生产环境,而演示文档则把这套方法封装成可复现、可验收、可混排的 evidence-first 交接示范。无论你是手动排查问题,还是让 AI 编码 Agent 接手性能工单,都可以直接复用这套流程与检查清单。
进一步阅读:技能总纲 SKILL.md、演示提示词 demo/PROMPT.md、时间剖析 references/time-profiler.md、内存剖析 references/memory-profiling.md、启动优化 references/launch-optimization.md、能耗诊断 references/energy-diagnostics.md。
【免费下载链接】Skills
Agent skills for designers and builders using Codex, Claude, Cursor, and other AI coding agents
相关推荐
Apple 平台应用性能剖析实战指南:Instruments、Xcode 诊断与 MetricKit 系统化排查方案
Apple 平台应用性能剖析实战指南:Instruments、Xcode 诊断与 MetricKit 系统化排查方案 本文以 Skills 仓库中 perfor
Apple 平台应用性能剖析实战:用 Instruments Time Profiler 与 Hang 检测定位卡顿与卡死
Apple 平台应用性能剖析实战:用 Instruments Time Profiler 与 Hang 检测定位卡顿与卡死 本文是基于 Skills 仓库中 p
Skills 仓库 performance-profiling 技能详解:Apple 平台内存剖析实战(Allocations、Leaks 与 Memory Graph Debugger)
Skills 仓库 performance profiling 技能详解:Apple 平台内存剖析实战(Allocations、Leaks 与 Memory G
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考