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 });

参考

相关推荐
景彬11 分钟前
小红书小组件开发 最早踩坑版
前端·微信小程序
mapbar_front28 分钟前
今天聊聊面试
前端·面试
华仔啊1 小时前
Vue3+CSS实现一个非常丝滑的 input 标签上浮动画,设计师看了都点赞
前端·css·vue.js
北海道浪子1 小时前
[免费送$1000]ClaudeCode、Codex等AI模型在开发中的使用
前端·人工智能·后端
明月与玄武1 小时前
2025 前端框架决战:Vue 与 React 分析优缺点及使用场景!
前端·vue.js·react.js
无盐海1 小时前
XSS漏洞攻击 (跨站脚本攻击)
前端·xss
不一样的少年_1 小时前
1024程序员节:用不到100行代码做个“代码雨屏保”装X神器(附源码)
前端·javascript·浏览器
阿奇__1 小时前
el-table默认排序设置
前端·javascript·vue.js
hongc931 小时前
element-ui el-table 设置固定列fixed 高度不对
前端·vue.js·elementui
Forfun_tt2 小时前
xss-labs pass-12
前端·xss