Long Animation Frames API(LoAF,发音为 Lo-Af)是对 Long Tasks API 的更新,旨在更好地了解界面 (UI) 更新缓慢的问题。这对于识别可能影响衡量响应速度的 Interaction to Next Paint (INP) Core Web Vital 指标的缓慢动画帧,或识别影响流畅度的其他界面卡顿非常有用。
API 的状态
在从 Chrome 116 到 Chrome 122 进行源试用后,LoAF API 已从 Chrome 123 开始提供。
背景知识:Long Tasks API
Long Animation Frames API 是 Long Tasks API 的替代方案,Long Tasks API 已在 Chrome 中推出一段时间了(自 Chrome 58 起)。顾名思义,借助 Long Task API,您可以监控长任务,即占用主线程 50 毫秒或更长时间的任务。您可以使用 PerformanceLongTaskTiming
界面和 PeformanceObserver
监控长时间运行的任务:
const observer = new PerformanceObserver((list) => {
console.log(list.getEntries());
});
observer.observe({ type: 'longtask', buffered: true });
长任务可能会导致响应速度问题。如果用户尝试与网页互动(例如点击按钮或打开菜单),但主线程正在处理耗时任务,则用户的互动会延迟,直到该任务完成。
为了提高响应速度,通常建议拆分耗时较长的任务。如果将每项长任务拆分为一系列较小的任务,则可以在这些任务之间执行更重要的任务,以避免在响应互动时出现明显延迟。
因此,在尝试提高响应速度时,通常首先要做的是运行性能轨迹并查看长时间运行的任务。您可以通过实验室审核工具(例如 Lighthouse,其中包含避免出现长时间运行的主线程任务审核)或在 Chrome 开发者工具中查看长时间运行的任务来进行检查。
在确定响应速度问题时,实验室测试通常不是好的起点,因为这些工具可能不包含互动,即使包含,也只是可能互动的一部分。理想情况下,您应衡量导致互动缓慢的原因。
Long Tasks API 的缺点
使用性能观察器衡量现场执行的长时间任务只有一些用处。实际上,除了发生了耗时任务以及耗时长短之外,它不会提供太多信息。
真实用户监控 (RUM) 工具通常使用此信息来分析耗时较长的任务的数量或持续时间,或确定发生这些任务的网页,但其用途有限,无法提供导致耗时较长的任务的基本详情。Long Tasks API 仅提供基本归因模型,该模型充其量只能告诉您发生长任务的容器(顶级文档或 <iframe>
),但无法告诉您调用该容器的脚本或函数,如下面的典型条目所示:
{
"name": "unknown",
"entryType": "longtask",
"startTime": 31.799999997019768,
"duration": 136,
"attribution": [
{
"name": "unknown",
"entryType": "taskattribution",
"startTime": 0,
"duration": 0,
"containerType": "window",
"containerSrc": "",
"containerId": "",
"containerName": ""
}
]
}
Long Tasks API 也是一个不完整的视图,因为它可能也会排除一些重要任务。某些更新(例如渲染)会在单独的任务中进行,理想情况下,应将导致该更新的先前执行操作包含在内,以准确衡量该互动的“总工作量”。如需详细了解依赖任务存在的限制,请参阅说明文档中的“耗时较长的任务的不足之处”部分。
最后一个问题是,衡量长时间运行的任务时,系统只会报告耗时超过 50 毫秒的各个任务。动画帧可以由多个小于 50 毫秒限制的任务组成,但这些任务总体上仍然会阻止浏览器渲染。
Long Animation Frames API
Long Animation Frames API (LoAF) 是一个新 API,旨在解决 Long Tasks API 的一些缺点,让开发者能够获得更实用的分析洞见,以帮助解决响应速度问题并提高 INP,还能深入了解流畅度问题。
良好的响应能力意味着网页能够快速响应与其进行的互动。这涉及能够及时绘制用户需要的任何更新,并避免阻止这些更新的发生。对于 INP,建议在 200 毫秒内响应,但对于其他更新(例如动画),即使 200 毫秒也可能过长。
Long Animation Frames API 是衡量阻塞工作的替代方法。顾名思义,Long Animation Frames API 用于衡量长动画帧,而不是衡量各个任务。长动画帧是指渲染更新的延迟超过 50 毫秒(与 Long Tasks API 的阈值相同)。
动画帧时长是从需要进行渲染的任务开始时计算的。如果潜在长动画帧中的第一个任务不需要渲染,则在非渲染任务完成后,长动画帧会结束,并在下一个任务开始时启动新的潜在长动画帧。当超过 50 毫秒(renderStart
时间为 0)时,此类非渲染长动画帧仍会包含在 Long Animation Frames API 中,以便衡量可能阻塞的工作。
观察较长的动画帧的方式与使用 PerformanceObserver
的耗时较长的任务类似,但应查看 long-animation-frame
类型:
const observer = new PerformanceObserver((list) => {
console.log(list.getEntries());
});
observer.observe({ type: 'long-animation-frame', buffered: true });
您还可以从性能时间轴查询之前的长动画帧,如下所示:
const loafs = performance.getEntriesByType('long-animation-frame');
不过,性能条目有 maxBufferSize
,之后系统会丢弃较新的条目,因此建议使用 PerformanceObserver 方法。long-animation-frame
缓冲区大小设置为 200,与 long-tasks
相同。
查看帧而非任务的好处
从帧的角度(而非任务的角度)来看这一点的主要优势在于,一个长动画可以由任意数量的任务组成,这些任务累积起来会产生一个长动画帧。这解决了前面提到的最后一点,即 Long Tasks API 可能不会显示动画帧之前许多较小渲染阻塞任务的总和。
对于耗时较长的任务,这种视图的另一个优势是能够提供整个帧的时间细分。与 Long Tasks API 不同,LoAF 不仅包含 startTime
和 duration
,还包含有关帧时长的各个部分的更详细的细分。
帧时间戳和时长
startTime
:长动画帧相对于导航开始时间的开始时间。duration
:长动画帧的时长(不包括呈现时间)。renderStart
:渲染周期的开始时间,包括requestAnimationFrame
回调、样式和布局计算、调整观察器的大小以及 Intersection Observer 回调。styleAndLayoutStart
:用于样式和布局计算的时间段的开始时间。firstUIEventTimestamp
:在此帧过程中要处理的第一个界面事件(鼠标/键盘等)的时间。blockingDuration
:动画帧会阻止处理输入或其他高优先级任务的总时长(以毫秒为单位)。
blockingDuration
说明
一个长动画帧可能由多个任务组成。blockingDuration
是超过 50 毫秒的任务时长的总和(包括最长任务的最终呈现时长)。
例如,如果一个长动画帧由两个任务(55 毫秒和 65 毫秒)组成,然后渲染 20 毫秒,则 duration
约为 140 毫秒,blockingDuration
为 (55 - 50) + (65 + 20 - 50) = 40 毫秒。在此时长为 140 毫秒的动画帧期间,处理 40 毫秒时,相应帧被视为被阻止处理输入。
是查看 duration
还是 blockingDuration
对于常见的 60 赫兹显示屏,浏览器会尝试至少每 16.66 毫秒调度一个帧(以确保流畅更新),或在输入处理等高优先级任务之后调度一个帧(以确保响应迅速的更新)。不过,如果没有输入,也没有其他高优先级任务,但有其他任务队列,则浏览器通常会在当前帧结束后很长时间(远远超过 16.66 毫秒)继续执行其他任务,无论这些任务在其中的分解程度如何。也就是说,浏览器始终会尝试优先处理输入,但可能会选择处理任务队列,而不是渲染更新。这是因为渲染是一项成本高昂的过程,因此为多项任务处理组合渲染任务通常会导致总体工作量减少。
因此,blockingDuration
较低或为零的长动画帧应该仍然能对输入做出响应。因此,根据 INP 的衡量结果,通过拆分耗时较长的任务来减少或消除 blockingDuration
是提升响应能力的关键。
不过,无论 blockingDuration
如何,大量的长动画帧都表示界面更新延迟,因此仍会影响流畅度,并导致滚动或动画的界面感觉迟缓,即使这些问题在 INP 衡量的响应速度方面不太严重也是如此。如需了解此方面的问题,请查看 duration
,但这些问题在优化方面可能更棘手,因为您无法通过拆分工作来解决此问题,而必须减少工作量。
帧时间
借助前面提到的时间戳,可以将长动画帧划分为以下时间点:
计时 | 计算 |
---|---|
开始时间 | startTime |
结束时间 | startTime + duration |
工作时长 | renderStart ? renderStart - startTime : duration |
渲染时长 | renderStart ? (startTime + duration) - renderStart: 0 |
渲染:布局前时长 | styleAndLayoutStart ? styleAndLayoutStart - renderStart : 0 |
呈现:样式和布局时长 | styleAndLayoutStart ? (startTime + duration) - styleAndLayoutStart : 0 |
更好的脚本归因
long-animation-frame
条目类型包含有助于较长动画帧(适用于时长超过 5 毫秒的脚本)的每个脚本的归因数据。
与 Long Tasks API 类似,此信息将以归因条目数组的形式提供,其中每个条目都详细说明了:
name
和EntryType
都会返回script
。- 一个有意义的
invoker
,用于指明脚本的调用方式(例如'IMG#id.onload'
、'Window.requestAnimationFrame'
或'Response.json.then'
)。 - 脚本入口点的
invokerType
:user-callback
:从 Web 平台 API 注册的已知回调(例如setTimeout
、requestAnimationFrame
)。event-listener
:平台事件(例如click
、load
、keyup
)的监听器。resolve-promise
:平台 Promise 的处理脚本(例如fetch()
。请注意,对于 Promise,同一 Promise 的所有处理脚本会混合在一起作为一个“脚本”.
reject-promise
:与resolve-promise
相同,但用于拒绝。classic-script
:脚本评估(例如<script>
或import()
)module-script
:与classic-script
相同,但适用于模块脚本。
- 该脚本的单独计时数据:
startTime
:条目函数被调用的时间。duration
:从startTime
到后续微任务队列完成处理之间的时长。executionStart
:编译后的时间。forcedStyleAndLayoutDuration
:在此函数内处理强制布局和样式的总时间(请参阅过载)。pauseDuration
:在“暂停”同步操作(提醒、同步 XHR)中花费的总时间。
- 脚本来源详情:
sourceURL
:脚本资源名称(如果有,否则为空)。sourceFunctionName
:脚本函数名称(如果有,否则为空)。sourceCharPosition
:脚本字符位置(如果可用,否则为 -1)。
windowAttribution
:出现长动画帧的容器(顶级文档或<iframe>
)。window
:对同源窗口的引用。
通过源代码条目(如果提供),开发者可以准确了解长动画帧中的每个脚本的调用方式,包括调用脚本中的字符位置。这会显示导致动画帧延迟的 JavaScript 资源中的确切位置。
long-animation-frame
效果条目示例
包含单个脚本的完整 long-animation-frame
效果条目示例如下:
{
"blockingDuration": 0,
"duration": 60,
"entryType": "long-animation-frame",
"firstUIEventTimestamp": 11801.099999999627,
"name": "long-animation-frame",
"renderStart": 11858.800000000745,
"scripts": [
{
"duration": 45,
"entryType": "script",
"executionStart": 11803.199999999255,
"forcedStyleAndLayoutDuration": 0,
"invoker": "DOMWindow.onclick",
"invokerType": "event-listener",
"name": "script",
"pauseDuration": 0,
"sourceURL": "https://web.dev/js/index-ffde4443.js",
"sourceFunctionName": "myClickHandler",
"sourceCharPosition": 17796,
"startTime": 11803.199999999255,
"window": [Window object],
"windowAttribution": "self"
}
],
"startTime": 11802.400000000373,
"styleAndLayoutStart": 11858.800000000745
}
如您所见,这为网站提供了前所未有的数据量,使其能够理解呈现更新延迟的原因。
在该字段中使用 Long Animation Frames API
虽然 Chrome 开发者工具和 Lighthouse 等工具有助于发现和重现问题,但它们是实验室工具,可能会忽略只有现场数据才能提供的用户体验重要方面。
Long Animation Frames API 旨在用于在现场收集用户互动的重要情境数据,而 Long Tasks API 无法做到这一点。这有助于您发现和重现您可能无法通过其他方式发现的交互性问题。
支持检测长动画帧的功能 API
您可以使用以下代码来测试是否支持该 API:
if (PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) {
// Monitor LoAFs
}
指向最长 INP 互动的指链
Long Animation Frames API 最明显的用例是帮助诊断和解决互动到下次绘制 (INP) 问题,这也是 Chrome 团队开发此 API 的主要原因之一。良好的 INP 是指从互动到帧绘制完成之间的所有互动在 200 毫秒或更短时间内得到响应,由于 Long Animation Frames API 会衡量所有耗时 50 毫秒或更长时间的帧,因此大多数有问题的 INP 应包含 LoAF 数据,以帮助您诊断这些互动。
“INP LoAF”是指包含 INP 互动的 LoAF,如以下图所示:
在某些情况下,INP 事件可能会跨越两个 LoAF,通常如果互动发生在帧开始渲染前一帧的渲染部分之后,那么事件处理脚本会在下一帧中处理:
在极少数情况下,它甚至可能跨越两个 LoAF。
通过记录与 INP 互动相关的 LoAF 数据,您可以获取有关 INP 互动的更多信息,以便进行诊断。这对了解输入延迟特别有帮助,因为您可以看到该帧中运行的其他脚本。
如果您的事件处理程序无法重现所见的处理时长和呈现延迟值,了解原因也非常有帮助,因为系统可能正在为您的用户运行其他脚本,而这些脚本可能未包含在您自己的测试中。
没有直接 API 可将 INP 条目与其相关的 LoAF 条目相关联,但可以通过比较每个 INP 条目的开始和结束时间,在代码中实现这一点(请参阅 WhyNp 示例脚本)。web-vitals
库包含 v4 中 INP 归因接口的 longAnimationFramesEntries
属性中的所有相交 LoAF。
关联一个或多个 LoAF 条目后,您可以添加 INP 归因的信息。scripts
对象包含一些最有价值的信息,因为它可以显示这些帧中运行的其他内容,因此将这些数据信标回传到您的分析服务后,您可以更深入地了解互动速度缓慢的原因。
报告 INP 互动中的 LoAF 是查找网页上最紧迫的互动问题的好方法。每位用户与您的网页的互动方式可能有所不同,如果 INP 归因数据量足够大,INP 归因数据中就会包含一些潜在问题。这样,您就可以按脚本量对脚本进行排序,以了解哪些脚本与 INP 速度缓慢相关。
将更多长动画数据报告回分析端点
仅查看 INP LoAF 的一个缺点是,您可能会错过其他可能导致未来 INP 问题的潜在改进领域。这可能会导致您陷入一种追逐尾巴的感觉:您解决一个 INP 问题,希望能取得巨大的改进,但发现下一个最慢的互动速度只比它快了一点,因此 INP 没有太大改善。
因此,您不应仅查看 INP LoAF,而应考虑网页生命周期内的所有 LoAF:
不过,每个 LoAF 条目都包含大量数据,因此您可能希望仅将分析范围限定为部分 LoAF。此外,由于长动画帧条目可能非常大,因此开发者应决定应将条目中哪些数据发送到 Google Analytics。例如,条目的摘要时间和脚本名称,或者可能被视为必要的其他一些最少量情境数据。
以下是减少长动画帧数据量的一些建议模式:
以下哪一种模式最适合您,取决于您在优化过程中所处的阶段,以及常见的动画帧数有多长。对于从未针对响应速度进行过优化的网站,可能存在许多 LoAF,因此您可能需要仅限于查看有互动的 LoAF,或者设置较高的阈值,或者仅查看最差的 LoAF。
在解决常见的响应速度问题后,您可以扩大范围,不局限于互动或高阻塞时长,也可以降低阈值。
观察包含互动的长动画帧
如需获得有关 INP 长动画帧以外的深入分析,您可以查看 blockingDuration
较高且包含互动(可通过 firstUIEventTimestamp
值的存在检测到)的所有 LoAF。
这也是一种更简单的监控 INP LoAF 的方法,而不是尝试建立这两者之间的关联(这可能更复杂)。在大多数情况下,这将包括给定访问的 INP LoAF;在极少数情况下,如果不包含 INP LoAF,系统仍会显示需要解决的重要的长时间互动,因为它们可能是其他用户的 INP 互动。
以下代码会记录在帧期间发生互动且 blockingDuration
大于 100 毫秒的所有 LoAF 条目。这里选择 100,是因为它低于 200 毫秒的“良好”INP 阈值。您可以根据需要选择更高或更低的值。
const REPORTING_THRESHOLD_MS = 100;
const observer = new PerformanceObserver(list => {
for (const entry of list.getEntries()) {
if (entry.blockingDuration > REPORTING_THRESHOLD_MS &&
entry.firstUIEventTimestamp > 0
) {
// Example here logs to console, but could also report back to analytics
console.log(entry);
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
观察阻塞时长较长的较长动画帧
为了便于查看所有包含互动的长动画帧,您可能需要查看阻塞时长较长的所有长动画帧。如果用户在这些长动画帧期间确实进行了互动,则这些指标表示可能存在 INP 问题。
以下代码会记录在帧期间发生互动且阻塞时长超过 100 毫秒的所有 LoAF 条目。之所以选择 100,是因为它低于 200 毫秒的“良好”INP 阈值,有助于识别潜在的问题帧,同时最大限度地减少报告的长动画帧数量。您可以根据需要选择较高或较低的值。
const REPORTING_THRESHOLD_MS = 100;
const observer = new PerformanceObserver(list => {
for (const entry of list.getEntries()) {
if (entry.blockingDuration > REPORTING_THRESHOLD_MS) {
// Example here logs to console, but could also report back to analytics
console.log(entry);
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
观察关键界面更新期间的长动画帧,以提高流畅度
如前所述,查看阻塞时长较长的动画帧有助于解决输入响应速度问题。但为了获得流畅度,您应查看所有具有长 duration
的长动画帧。
由于这会非常嘈杂,因此您需要使用以下模式将这些值的测量限制在关键点:
const REPORTING_THRESHOLD_MS = 100;
const observer = new PerformanceObserver(list => {
if (measureImportantUIupdate) {
for (const entry of list.getEntries()) {
if (entry.duration > REPORTING_THRESHOLD_MS) {
// Example here logs to console, but could also report back to analytics
console.log(entry);
}
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
async function doUIUpdatesWithMeasurements() {
measureImportantUIupdate = true;
await doUIUpdates();
measureImportantUIupdate = false;
}
观察最长的动画帧
网站可能希望收集最长动画帧的数据,而不是设置阈值,以减少需要发送信标的数据量。因此,无论网页出现多少个长动画帧,系统只会回传最糟糕的 1 个、5 个、10 个或绝对必要的任意数量的长动画帧的数据。
MAX_LOAFS_TO_CONSIDER = 10;
let longestBlockingLoAFs = [];
const observer = new PerformanceObserver(list => {
longestBlockingLoAFs = longestBlockingLoAFs.concat(list.getEntries()).sort(
(a, b) => b.blockingDuration - a.blockingDuration
).slice(0, MAX_LOAFS_TO_CONSIDER);
});
observer.observe({ type: 'long-animation-frame', buffered: true });
这些策略也可以组合使用,例如只查看互动时间超过 100 毫秒的 10 个最差 LoAF。
在适当的时间(最好是在 visibilitychange
事件中)将信标发回到 Google Analytics。对于本地测试,您可以定期使用 console.table
:
console.table(longestBlockingLoAFs);
识别长动画帧中的常见模式
另一种策略是查看长动画帧条目中出现最多的常用脚本。系统可能会在脚本和角色位置报告相关数据,以识别屡次违规者。
这对于可自定义的平台尤其适用,因为在这种平台上,您可以跨多个网站找出导致性能问题的主题或插件。
可以汇总并报告长动画帧中常见脚本(或第三方来源)的执行时间,以确定一个网站或一系列网站中长动画帧的常见原因。例如,如需查看网址,请执行以下操作:
const observer = new PerformanceObserver(list => {
const allScripts = list.getEntries().flatMap(entry => entry.scripts);
const scriptSource = [...new Set(allScripts.map(script => script.sourceURL))];
const scriptsBySource= scriptSource.map(sourceURL => ([sourceURL,
allScripts.filter(script => script.sourceURL === sourceURL)
]));
const processedScripts = scriptsBySource.map(([sourceURL, scripts]) => ({
sourceURL,
count: scripts.length,
totalDuration: scripts.reduce((subtotal, script) => subtotal + script.duration, 0)
}));
processedScripts.sort((a, b) => b.totalDuration - a.totalDuration);
// Example here logs to console, but could also report back to analytics
console.table(processedScripts);
});
observer.observe({type: 'long-animation-frame', buffered: true});
输出示例如下:
(index) |
sourceURL |
count |
totalDuration |
---|---|---|---|
0 |
'https://example.consent.com/consent.js' |
1 |
840 |
1 |
'https://example.com/js/analytics.js' |
7 |
628 |
2 |
'https://example.chatapp.com/web-chat.js' |
1 |
5 |
在工具中使用 Long Animation Frames API
该 API 还允许使用其他开发者工具进行本地调试。虽然 Lighthouse 和 Chrome DevTools 等一些工具能够使用更低级的跟踪详细信息收集其中的大部分数据,但有了这个更高级的 API,其他工具也能访问这些数据。
在开发者工具中显示长动画帧数据
您可以使用 performance.measure()
API 在 DevTools 中显示长动画帧,这些帧随后会显示在性能轨迹的 DevTools 用户时间轨道中,以显示您应在哪些方面着力改进性能。使用 DevTools 可扩展性 API,这些甚至可以在各自的轨道中显示:
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
performance.measure('LoAF', {
start: entry.startTime,
end: entry.startTime + entry.duration,
detail: {
devtools: {
dataType: "track-entry",
track: "Long animation frames",
trackGroup: "Performance Timeline",
color: "tertiary-dark",
tooltipText: 'LoAF'
}
}
});
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
从长远来看,长动画帧很可能会包含在开发者工具中,但之前的代码段允许同时在开发者工具中显示动画帧。
上图中的第一个条目还展示了浏览器在同一个长动画帧中同时处理多个任务而不是在这些任务之间渲染的位置。如前所述,当没有高优先级输入任务,但有任务队列时,就可能会发生这种情况。第一个长任务需要完成一些渲染更新(否则,当前的长动画帧会在完成后重置,并在下一个任务开始时开始新的长动画帧),但浏览器并未立即执行该渲染,而是处理了一些其他任务,然后才执行长渲染任务并结束长动画帧。这表明在开发者工具中查看长动画帧(而不仅仅是长任务)有助于识别延迟渲染非常有用。
在其他开发者工具中使用长动画帧数据
Web Vitals 扩展程序已在日志摘要调试信息中显示该值,以便诊断性能问题。
现在,它还会显示每个 INP 回调和每次互动的长动画帧数据:
在自动化测试工具中使用长动画帧数据
同样,CI/CD 流水线中的自动化测试工具可以通过在运行各种测试套件时测量长动画帧来揭示潜在性能问题的详细信息。
常见问题解答
有关此 API 的一些常见问题包括:
为什么不直接扩展或迭代 Long Tasks API?
这是一种报告类似(但最终不同的)潜在响应能力问题的替代方法。请务必确保依赖现有 Long Tasks API 的网站能够继续正常运行,以免影响现有用例。
虽然 Long Tasks API 可能会受益于 LoAF 的一些功能(例如更好的归因模型),但我们认为,专注于帧而非任务会带来诸多好处,这使得该 API 与现有的 Long Tasks API 截然不同。
为什么我没有脚本条目?
这可能表明动画帧延迟时间长的原因不是 JavaScript,而是大量渲染工作。
如果长动画帧是由 JavaScript 导致的,但由于前面提到的各种隐私原因(主要是 JavaScript 不归网页所有),无法提供脚本提供方信息,也可能会出现这种情况。
为什么我有脚本条目,但没有或只有有限的来源信息?
造成这种情况的原因有很多,包括没有合适的来源可供参考。
no-cors cross-origin
脚本的脚本信息也会受到限制,不过您可以通过向 <script>
调用添加 crossOrigin = "anonymous"
,使用 CORS 提取这些脚本来解决此问题。
例如,要添加到网页中的默认 Google 跟踪代码管理器脚本:
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->
可以通过添加 j.crossOrigin = "anonymous"
进行增强,以便为 GTM 提供完整的归因详细信息
这会取代 Long Tasks API 吗?
虽然我们认为 Long Animation Frames API 是用于衡量长任务的更好、更完整的 API,但目前没有计划废弃 Long Tasks API。
期待反馈
您可以在 GitHub 问题列表中提供反馈,也可以在 Chrome 问题跟踪器中提交 Chrome 实现该 API 时出现的 bug。
总结
Long Animation Frames API 是一款令人兴奋的新 API,与之前的 Long Tasks API 相比,它具有许多潜在优势。
事实证明,它是解决 INP 衡量到的响应速度问题的关键工具。INP 是一个难以优化的指标,Chrome 团队正努力通过此 API 帮助开发者更轻松地发现和解决问题。
不过,Long Animation Frames API 的范围不仅仅局限于 INP,它还可以帮助找出导致更新缓慢的其他原因,这些原因可能会影响网站用户体验的整体顺畅度。