概念定义
用户对交互延迟的感知以帧为粒度:点击在下一个呈现帧出现前毫无意义。LoAF 上报每个超过 50 毫秒的帧,拆解时间去向并点名涉事脚本,把卡顿从体感变成可归因数据。
工作机制
类型为 long-animation-frame 的 PerformanceObserver 收到条目,携带 startTime、duration,以及含调用者信息与源码字符位置的脚本归因记录;渲染各阶段时长分别列出样式、布局、绘制与提交。配合元素计时可回溯到具体函数。
使用场景
面向 INP 优化的生产 RUM、发版后的回归分诊、第三方影响审计。帧事件量极大且归因载荷不小,接入遥测管线时应做采样。
常见误区
长任务只看任务,长帧覆盖整条管线:布局与绘制撑爆的帧里任务可能很小,长任务口径会漏掉。归因指向 bundle 而非意图,压缩后的代码需要 source map 才可执行。跨交互边界的帧可能重复计数,应与事件时序条目关联;旧浏览器只有长任务,管线要兼容两种条目。
代码示例
public class StringBuilderManipulation {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder(64);
sb.append("Hello");
sb.append(" ");
sb.append("World");
System.out.println("Built: " + sb);
sb.insert(5, " Java");
System.out.println("After insert: " + sb);
sb.delete(5, 10);
System.out.println("After delete: " + sb);
sb.replace(0, 5, "Hi");
System.out.println("After replace: " + sb);
sb.reverse();
System.out.println("Reversed: " + sb);
String csv = String.join(", ",
"Apple", "Banana", "Cherry", "Date");
System.out.println("CSV: " + csv);
String formatted = String.format(
"Name: %s, Age: %d, Score: %.2f",
"Alice", 30, 95.5
);
System.out.println(formatted);
String stripped = " padded ".strip();
System.out.println("Stripped: '" + stripped + "'");
}
}