给 LLM 喂什么:profile 数据的三种裁剪方式
给 LLM 喂什么:profile 数据的三种裁剪方式

在构建前端性能智能诊断 Agent 时,所有架构师面临的第一道核心工程难关就是:如何处理 Chrome 导出的庞大 Performance Profile 数据?
一份录制了 5 秒用户交互的真实 Chrome Trace JSON 文件,体积通常在 30MB 到 150MB 之间,内部包含了几十万个底层事件(Event Slices)、V8 内部元数据、线程通信管道日志以及海量的 GPU 光栅化坐标。
直接把整份文件喂给大模型显然是天方夜谭(瞬间爆掉 Context Window)。而如果粗暴地只截取头部的 1000 行,模型拿到的全是无意义的环境初始化元数据。
要让大模型在有限的上下文预算(例如 4k ~ 16k Tokens)内精准命中瓶颈,必须对 Profile 数据进行多维度的数学降维与特征裁剪。
本文深度拆解我们在生产实践中验证过的 三种 Profile 数据裁剪范式与适用场景。
三种裁剪方式的架构对比
┌─────────────────────────────────────────────────────────────┐
│ 方式 1: 瓶颈聚合裁剪 (Bottleneck Top-down Aggregation) │
│ - 提取: Top-N Self Time / Total Time 聚合热点表 │
│ - 体积: ~ 1.5 KB │
│ - 场景: 快速初筛、CI 自动化门禁、高频快速体检 │
├─────────────────────────────────────────────────────────────┤
│ 方式 2: 时序长任务切片裁剪 (Long Task Timeline Slicing) │
│ - 提取: 耗时 > 50ms 的长任务上下文及微观嵌套调用栈 │
│ - 体积: ~ 8.0 KB │
│ - 场景: 用户交互掉帧(INP / 冻结)靶向排查 │
├─────────────────────────────────────────────────────────────┤
│ 方式 3: 渲染管线多维特征融合 (Pipeline Multi-track Distill) │
│ - 提取: 主线程 JS + 强制回流计数 + 网络瀑布 + 帧率关联图 │
│ - 体积: ~ 12.0 KB │
│ - 场景: 复杂大促活动页、万级表格全链路深度会诊 │
└─────────────────────────────────────────────────────────────┘
裁剪方式 1:瓶颈聚合热点表(Top-down Aggregation)
核心原理
跳过所有的时序发生细节,仅通过采样点(Samples)统计每个函数在全生命周期内的 自身耗时(Self Time) 与 总耗时(Total Time),按耗时倒序输出一个紧凑的 Markdown 表格。
// 数据形态示例 (输入给 LLM 的 Prompt 片段)
[Top 5 CPU 耗时函数清单]
1. `filterTreeNodes` (src/utils/tree.ts:84) - Self: 340ms (48.2%), Total: 410ms
2. `deepClone` (src/utils/clone.ts:12) - Self: 180ms (25.5%), Total: 180ms
3. `calculateLayout` (src/views/Canvas.vue:120) - Self: 60ms (8.5%), Total: 520ms
优劣分析
- 优势:体积极限小(< 2KB),Token 消耗微乎其微,对纯 CPU 密集型死循环、复杂递归算法的定位准确率高达 95%;
- 劣势:丢失了时间序列信息,无法看出函数是在页面初次挂载时执行的,还是在用户点击按钮时执行的。
裁剪方式 2:时序长任务切片(Long Task Slicing)
核心原理
过滤掉所有小于 50ms 的微小事件,仅将主线程上发生的长任务(Long Task)提取为一个独立的微型调用树(Sub-calltree),并保留其发生的时间戳与父子调用链。
// scripts/slice-long-tasks.ts
export function extractLongTaskSlices(traceEvents: any[]) {
const longTasks = traceEvents.filter(
(e) => e.name === 'RunTask' && (e.dur || 0) >= 50000 // >= 50ms
);
return longTasks.map((task) => ({
startTime: `${(task.ts / 1000).toFixed(1)} ms`,
duration: `${(task.dur / 1000).toFixed(1)} ms`,
// 递归提取该长任务内部耗时最长的主干调用栈
callStack: extractCriticalPath(task),
}));
}
// 数据形态示例
[
{
"taskDuration": "184.2 ms",
"triggerPhase": "User Click on Button#submit",
"callChain": "handleClick (Order.vue:45) -> submitOrder -> validateForm -> validateComplexRegexp (validator.ts:112)"
}
]
优劣分析
- 优势:能够清晰还原“某个特定的用户手势触发了哪一条长任务调用链”,非常适合治理新一代 Web Vitals 交互指标 INP(Interaction to Next Paint);
- 劣势:如果页面上存在数十个连续的 40ms 任务(虽然不是 Long Task 但累积造成卡顿),可能会被该规则漏网。
裁剪方式 3:渲染管线多维特征融合(Multi-track Distill)
核心原理
将主线程计算、渲染引擎行为(Layout / Paint / Composite)与网络资源下载三个原本分离的泳道进行关联聚合,输出一份结构化指标画像:
{
"summary": { "totalDuration": "4.8s", "droppedFrameCount": 18 },
"forcedLayoutMetrics": {
"totalCount": 42,
"worstCulpritLocation": "src/components/Table/VirtualRow.vue:89",
"associatedJsFunction": "updateRowOffset"
},
"networkBottlenecks": [
{ "url": "/assets/echarts.bundle.js", "size": "840KB", "blockingDuration": "1.2s" }
],
"topCpuHotspots": [
{ "func": "computeMatrix", "file": "src/math/matrix.ts:32", "selfTime": "420ms" }
]
}
优劣分析
- 优势:信息密度极高,给大模型提供了完整的“全景证据链”。模型可以推理出“因为网络加载了超大 JS,导致主线程解析阻塞,随后在组件挂载时触发了 42 次强制同步回流”这种深层跨阶段因果链路。
- 劣势:需要编写稍微复杂的 Trace 解析器,输入 Token 占用约 10k ~ 15k。
选型与落地方案推荐
在生产自动化流水线中,我们推荐采用**“渐进式两阶段裁剪策略”**:
[流水线触发性能分析]
│
▼ (第一阶段: 使用【方式 1 瓶颈聚合】进行 2 秒快速体检)
├── 若仅发现简单的单一函数算力过高 ──> 直接输出修复 Diff,流程结束
│
└── 若存在复杂的交互卡顿与回流 ──> 升级触发【方式 3 多维特征融合】进行深度会诊
通过这套裁剪分流策略,团队在保障 90% 以上诊断准确率 的同时,将单次调用的 Token 账单削减了 75%。
更多推荐


所有评论(0)