LCP 结果与性能 API 完全相反,而不是 pagespeed insights 或 webpagetest
LCP result is totally opposite from performance API than the pagespeed insights or webpagetest
我正在尝试优化 LCP for this page。我阅读了一篇关于 LCP 优化的文章,其中我还找到了一个脚本,它可以帮助确定 LCP 的哪一部分花费了最多的时间。脚本:
const LCP_SUB_PARTS = [
'Time to first byte',
'Resource load delay',
'Resource load time',
'Element render delay',
];
new PerformanceObserver((list) => {
const lcpEntry = list.getEntries().at(-1);
const navEntry = performance.getEntriesByType('navigation')[0];
const lcpResEntry = performance
.getEntriesByType('resource')
.filter((e) => e.name === lcpEntry.url)[0];
// Ignore LCP entries that aren't images to reduce DevTools noise.
// Comment this line out if you want to include text entries.
if (!lcpEntry.url) return;
// Compute the start and end times of each LCP sub-part.
// WARNING! If your LCP resource is loaded cross-origin, make sure to add
// the `Timing-Allow-Origin` (TAO) header to get the most accurate results.
const ttfb = navEntry.responseStart;
const lcpRequestStart = Math.max(
ttfb,
// Prefer `requestStart` (if TOA is set), otherwise use `startTime`.
lcpResEntry ? lcpResEntry.requestStart || lcpResEntry.startTime : 0
);
const lcpResponseEnd = Math.max(
lcpRequestStart,
lcpResEntry ? lcpResEntry.responseEnd : 0
);
const lcpRenderTime = Math.max(
lcpResponseEnd,
// Prefer `renderTime` (if TOA is set), otherwise use `loadTime`.
lcpEntry ? lcpEntry.renderTime || lcpEntry.loadTime : 0
);
// Clear previous measures before making new ones.
// Note: due to a bug this does not work in Chrome DevTools.
// LCP_SUB_PARTS.forEach(performance.clearMeasures);
// Create measures for each LCP sub-part for easier
// visualization in the Chrome DevTools Performance panel.
const lcpSubPartMeasures = [
performance.measure(LCP_SUB_PARTS[0], {
start: 0,
end: ttfb,
}),
performance.measure(LCP_SUB_PARTS[1], {
start: ttfb,
end: lcpRequestStart,
}),
performance.measure(LCP_SUB_PARTS[2], {
start: lcpRequestStart,
end: lcpResponseEnd,
}),
performance.measure(LCP_SUB_PARTS[3], {
start: lcpResponseEnd,
end: lcpRenderTime,
}),
];
// Log helpful debug information to the console.
console.log('LCP value: ', lcpRenderTime);
console.log('LCP element: ', lcpEntry.element);
console.table(
lcpSubPartMeasures.map((measure) => ({
'LCP sub-part': measure.name,
'Time (ms)': measure.duration,
'% of LCP': `${
Math.round((1000 * measure.duration) / lcpRenderTime) / 10
}%`,
}))
);
}).observe({type: 'largest-contentful-paint', buffered: true});
对我来说,这是开始时 4 倍 CPU 减速和 Fast3G 连接的结果。
在那之后,由于渲染延迟是我应该关注的领域,我将一些脚本移到了页脚,并将“延迟”脚本设为“异步”。这是结果:
我们可以看到更改后 LCP 有明显的改进,但是,当我使用灯塔进行测试时,结果有所不同。
之前:
之后:
我现在对采取什么步骤感到进退两难。请推荐!!
我 运行 您在问题中链接的 URL 的痕迹,我注意到的第一件事是您的 LCP 资源在页面中很早就完成加载,但事实并非如此能够呈现,直到名为 mirage2.min.js
的文件完成加载。
这解释了为什么 LCP 的“元素呈现延迟”部分如此长,将脚本移至页面底部或查看其中的 defer
并不能解决该问题。解决方案是让您的 LCP 图像可以渲染,而无需等到 JavaScript 文件完成加载。
我注意到的另一件事是这个 mirage2.min.js
文件是从 ajax.cloudflare.com
加载的,这让我认为这是 Cloudflare 提供的“功能”,而不是您自己设置的东西。
根据我在这里看到的内容,我假设这是真的:
https://support.cloudflare.com/hc/en-us/articles/219178057
所以我建议您关闭此功能,因为它显然对您的 LCP 没有帮助,正如您在此跟踪中看到的那样:
你说的还有一件事我认为值得澄清:
After that, since render delay was the area where I should focus on, I moved some of the scripts to the footer and also made the "deferred" scripts "async". This is the result:
当我查看您的“结果”屏幕截图时,我仍然看到“元素渲染延迟”部分仍然 > 50%,所以当您说“渲染延迟是我应该的区域”时您是正确的专注于”,事实上在您进行更改后它仍然很高(例如移动脚本并使用 defer/async)表明您尝试的更改没有解决问题。
在这种情况下,我相信如果您关闭 Cloudflare 仪表板中的“Mirage”功能,您应该会看到很大的改进。
哦,还有一件事,我注意到您在图片上使用了 importance="high"
。这是不再有效的旧语法。您应该将其替换为 fetchpriority="high"
。有关详细信息,请参阅此 post:https://web.dev/priority-hints/
我正在尝试优化 LCP for this page。我阅读了一篇关于 LCP 优化的文章,其中我还找到了一个脚本,它可以帮助确定 LCP 的哪一部分花费了最多的时间。脚本:
const LCP_SUB_PARTS = [
'Time to first byte',
'Resource load delay',
'Resource load time',
'Element render delay',
];
new PerformanceObserver((list) => {
const lcpEntry = list.getEntries().at(-1);
const navEntry = performance.getEntriesByType('navigation')[0];
const lcpResEntry = performance
.getEntriesByType('resource')
.filter((e) => e.name === lcpEntry.url)[0];
// Ignore LCP entries that aren't images to reduce DevTools noise.
// Comment this line out if you want to include text entries.
if (!lcpEntry.url) return;
// Compute the start and end times of each LCP sub-part.
// WARNING! If your LCP resource is loaded cross-origin, make sure to add
// the `Timing-Allow-Origin` (TAO) header to get the most accurate results.
const ttfb = navEntry.responseStart;
const lcpRequestStart = Math.max(
ttfb,
// Prefer `requestStart` (if TOA is set), otherwise use `startTime`.
lcpResEntry ? lcpResEntry.requestStart || lcpResEntry.startTime : 0
);
const lcpResponseEnd = Math.max(
lcpRequestStart,
lcpResEntry ? lcpResEntry.responseEnd : 0
);
const lcpRenderTime = Math.max(
lcpResponseEnd,
// Prefer `renderTime` (if TOA is set), otherwise use `loadTime`.
lcpEntry ? lcpEntry.renderTime || lcpEntry.loadTime : 0
);
// Clear previous measures before making new ones.
// Note: due to a bug this does not work in Chrome DevTools.
// LCP_SUB_PARTS.forEach(performance.clearMeasures);
// Create measures for each LCP sub-part for easier
// visualization in the Chrome DevTools Performance panel.
const lcpSubPartMeasures = [
performance.measure(LCP_SUB_PARTS[0], {
start: 0,
end: ttfb,
}),
performance.measure(LCP_SUB_PARTS[1], {
start: ttfb,
end: lcpRequestStart,
}),
performance.measure(LCP_SUB_PARTS[2], {
start: lcpRequestStart,
end: lcpResponseEnd,
}),
performance.measure(LCP_SUB_PARTS[3], {
start: lcpResponseEnd,
end: lcpRenderTime,
}),
];
// Log helpful debug information to the console.
console.log('LCP value: ', lcpRenderTime);
console.log('LCP element: ', lcpEntry.element);
console.table(
lcpSubPartMeasures.map((measure) => ({
'LCP sub-part': measure.name,
'Time (ms)': measure.duration,
'% of LCP': `${
Math.round((1000 * measure.duration) / lcpRenderTime) / 10
}%`,
}))
);
}).observe({type: 'largest-contentful-paint', buffered: true});
对我来说,这是开始时 4 倍 CPU 减速和 Fast3G 连接的结果。
在那之后,由于渲染延迟是我应该关注的领域,我将一些脚本移到了页脚,并将“延迟”脚本设为“异步”。这是结果:
我们可以看到更改后 LCP 有明显的改进,但是,当我使用灯塔进行测试时,结果有所不同。
之前:
之后:
我现在对采取什么步骤感到进退两难。请推荐!!
我 运行 您在问题中链接的 URL 的痕迹,我注意到的第一件事是您的 LCP 资源在页面中很早就完成加载,但事实并非如此能够呈现,直到名为 mirage2.min.js
的文件完成加载。
这解释了为什么 LCP 的“元素呈现延迟”部分如此长,将脚本移至页面底部或查看其中的 defer
并不能解决该问题。解决方案是让您的 LCP 图像可以渲染,而无需等到 JavaScript 文件完成加载。
我注意到的另一件事是这个 mirage2.min.js
文件是从 ajax.cloudflare.com
加载的,这让我认为这是 Cloudflare 提供的“功能”,而不是您自己设置的东西。
根据我在这里看到的内容,我假设这是真的: https://support.cloudflare.com/hc/en-us/articles/219178057
所以我建议您关闭此功能,因为它显然对您的 LCP 没有帮助,正如您在此跟踪中看到的那样:
你说的还有一件事我认为值得澄清:
After that, since render delay was the area where I should focus on, I moved some of the scripts to the footer and also made the "deferred" scripts "async". This is the result:
当我查看您的“结果”屏幕截图时,我仍然看到“元素渲染延迟”部分仍然 > 50%,所以当您说“渲染延迟是我应该的区域”时您是正确的专注于”,事实上在您进行更改后它仍然很高(例如移动脚本并使用 defer/async)表明您尝试的更改没有解决问题。
在这种情况下,我相信如果您关闭 Cloudflare 仪表板中的“Mirage”功能,您应该会看到很大的改进。
哦,还有一件事,我注意到您在图片上使用了 importance="high"
。这是不再有效的旧语法。您应该将其替换为 fetchpriority="high"
。有关详细信息,请参阅此 post:https://web.dev/priority-hints/