WebPerf Snippets 直接可以在浏览器控制台中获取网页性能指标的代码片段

分享社区里的精选的代码段列表,用于获取 Web 性能指标,可以非常方便地在浏览器控制台中使用,或在 Chrome DevTools 上用作运行的代码段。

如何使用?

所有代码段均在 Google Chrome 中进行测试,因此请使用此浏览器来确保正确的功能~

在 Chrome DevTools 中作为代码段运行

你可以在 Chrome DevTools 的 Sources 标签页中将 webperf-snippets 用作代码段。

  1. 复制任何 WebPerf 代码段

  2. 打开 Chrome DevTools(在新选项卡中打开)

  3. 选择Sources选项卡

  4. 选择 Snippets 子选项卡

  5. LCP(opens in a new tab)(在新选项卡中打开)点击New snippet按钮,例如 LCP

  6. 命名代码段名称 LCP

  7. 将复制的代码粘贴到右侧区域

  8. 运行代码段 Ctrl + Enter

代码

累计布局偏移 Cumulative Layout Shift (CLS)

当浏览器的焦点切换到另一个选项卡时,此脚本显示 CLS 值,因为 CLS 是在页面的生命周期内计算的。

js 复制代码
let cumulativeLayoutShiftScore = 0;
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!entry.hadRecentInput) {
      cumulativeLayoutShiftScore += entry.value;
    }
  }
});
 
observer.observe({ type: "layout-shift", buffered: true });
 
document.addEventListener("visibilitychange", () => {
  if (document.visibilityState === "hidden") {
    observer.takeRecords();
    observer.disconnect();
 
    console.log(`CLS: ${cumulativeLayoutShiftScore}`);
  }
});

最大内容绘制 Largest Contentful Paint (LCP)

在控制台中列出最大的内容绘制,并在 LCP 元素周围添加一条绿色虚线。

js 复制代码
const po = new PerformanceObserver((list) => {
  let entries = list.getEntries();
 
  entries = dedupe(entries, "startTime");
 
  entries.forEach((item, i) => {
    console.dir(item);
    console.log(
      `${i + 1} current LCP item : ${item.element}: ${item.startTime}`,
    );
    item.element ? (item.element.style = "border: 5px dotted lime;") : "";
  });
 
  const lastEntry = entries[entries.length - 1];
  console.log(`LCP is: ${lastEntry.startTime}`);
});
 
po.observe({ type: "largest-contentful-paint", buffered: true });
 
function dedupe(arr, key) {
  return [...new Map(arr.map((item) => [item[key], item])).values()];
}

最大的内容绘制 LCP,Quick BPP(图像熵)检查

使用该脚本,可以获取站点上加载的所有图像的 BPP 列表。

忽略源为"data:image"的图片和第三方图片。
上下文:Chrome 112 对最大内容绘制指标进行更改,可忽略低熵图像

js 复制代码
console.table(
  [...document.images]
    .filter(
      (img) => img.currentSrc != "" && !img.currentSrc.includes("data:image"),
    )
    .map((img) => [
      img.currentSrc,
      (performance.getEntriesByName(img.currentSrc)[0]?.encodedBodySize * 8) /
        (img.width * img.height),
    ])
    .filter((img) => img[1] !== 0),
);

最大内容渲染时间 Largest Contentful Paint Sub-Parts (LCP)

js 复制代码
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];
 
  const ttfb = navEntry.responseStart;
  const lcpRequestStart = Math.max(
    ttfb,
    lcpResEntry ? lcpResEntry.requestStart || lcpResEntry.startTime : 0,
  );
  const lcpResponseEnd = Math.max(
    lcpRequestStart,
    lcpResEntry ? lcpResEntry.responseEnd : 0,
  );
  const lcpRenderTime = Math.max(
    lcpResponseEnd,
    lcpEntry ? lcpEntry.startTime : 0,
  );
 
  LCP_SUB_PARTS.forEach((part) => performance.clearMeasures(part));
 
  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, lcpEntry?.url);
  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 });

参考

相关推荐
好玩的Matlab(NCEPU)17 分钟前
如何编写 Chrome 插件(Chrome Extension)
前端·chrome
Yan-英杰22 分钟前
Deepseek大模型结合Chrome搜索爬取2025AI投资趋势数据
前端·chrome
Crystal32833 分钟前
app里video层级最高导致全屏视频上的操作的东西显示不出来的问题
前端·vue.js
weixin_4454766835 分钟前
Vue+redis全局添加水印解决方案
前端·vue.js·redis
lecepin36 分钟前
AI Coding 资讯 2025-10-29
前端·后端·面试
余道各努力,千里自同风1 小时前
小程序中获取元素节点
前端·小程序
PineappleCoder1 小时前
大模型也栽跟头的 Promise 题!来挑战一下?
前端·面试·promise
非凡ghost1 小时前
MousePlus(鼠标增强工具) 中文绿色版
前端·windows·计算机外设·软件需求
焚 城1 小时前
EXCEL(带图)转html【uni版】
前端·html·excel
我家媳妇儿萌哒哒1 小时前
Vue2 elementUI年份区间选择组件
前端·javascript·elementui