← 全部文章

API 与辅助工具

标签页里的 Web Vitals 监视器 —— 在 Output Console 里看 LCP / CLS / INP,无需 DevTools

Web Vitals(LCP、CLS、INP)是 Google 用作 SEO 排名因素的 3 个指标。测量它们的标准方式:DevTools 里的 Lighthouse —— 每次审计 30 秒,手动触发。替代方案:浏览器内置的 PerformanceObserver API。外加一条 JustZix JS 规则 = 一个被动监视器,为每个访问的页面在 Output Console 里报告。非常适合快速检查自己的项目或分析竞争对手。

JS 规则 —— 完整捕获 Web Vitals

作用域:*://*/*,或者如果你只想监控自己的网站就按域名。

// JS 规则「Web Vitals 监视器」
const vitals = { LCP: null, CLS: 0, FCP: null, TTFB: null, INP: null };

// === LCP (Largest Contentful Paint) ===
new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const last = entries[entries.length - 1];
  vitals.LCP = Math.round(last.startTime);
}).observe({ type: 'largest-contentful-paint', buffered: true });

// === CLS (Cumulative Layout Shift) ===
let clsEntries = [];
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!entry.hadRecentInput) {
      clsEntries.push(entry);
      vitals.CLS = clsEntries.reduce((s, e) => s + e.value, 0);
    }
  }
}).observe({ type: 'layout-shift', buffered: true });

// === FCP (First Contentful Paint) ===
new PerformanceObserver((list) => {
  const fcp = list.getEntries().find(e => e.name === 'first-contentful-paint');
  if (fcp) vitals.FCP = Math.round(fcp.startTime);
}).observe({ type: 'paint', buffered: true });

// === TTFB (Time to First Byte) ===
const nav = performance.getEntriesByType('navigation')[0];
if (nav) vitals.TTFB = Math.round(nav.responseStart - nav.requestStart);

// === INP (Interaction to Next Paint) ===
let worstINP = 0;
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.duration > worstINP) {
      worstINP = Math.round(entry.duration);
      vitals.INP = worstINP;
    }
  }
}).observe({ type: 'event', buffered: true, durationThreshold: 16 });

// 加载后 5 秒报告 + 在 unload 时报告(最终值)
const report = () => {
  const status = (val, good, poor) =>
    val === null ? '?' : val <= good ? '✓' : val <= poor ? '⚠' : '✗';

  JUSTZIX.log('=== Web Vitals ===');
  JUSTZIX.log(`LCP:  ${vitals.LCP ?? '?'}ms  ${status(vitals.LCP, 2500, 4000)} (目标 <2.5s)`);
  JUSTZIX.log(`CLS:  ${vitals.CLS.toFixed(3)}  ${status(vitals.CLS, 0.1, 0.25)} (目标 <0.1)`);
  JUSTZIX.log(`FCP:  ${vitals.FCP ?? '?'}ms  ${status(vitals.FCP, 1800, 3000)} (目标 <1.8s)`);
  JUSTZIX.log(`TTFB: ${vitals.TTFB ?? '?'}ms  ${status(vitals.TTFB, 800, 1800)} (目标 <800ms)`);
  JUSTZIX.log(`INP:  ${vitals.INP ?? '?'}ms  ${status(vitals.INP, 200, 500)} (目标 <200ms)`);
};

setTimeout(report, 5000);
window.addEventListener('beforeunload', report);
JUSTZIX.info(`[Vitals] 监视器已为 ${location.hostname} 激活`);

你在 Output Console 里看到什么

加载后 5 秒:

[INFO]  [Vitals] 监视器已为 www.justzix.com 激活
[LOG]   === Web Vitals ===
[LOG]   LCP:  1240ms  ✓ (目标 <2.5s)
[LOG]   CLS:  0.024   ✓ (目标 <0.1)
[LOG]   FCP:  680ms   ✓ (目标 <1.8s)
[LOG]   TTFB: 145ms   ✓ (目标 <800ms)
[LOG]   INP:  85ms    ✓ (目标 <200ms)

每个指标带一个视觉状态:

使用场景 1 —— 不用 Lighthouse 审计自己的网站

经典:部署到 staging,打开标签页,检查 Web Vitals 是否都是绿的。用 Lighthouse:等 30 秒。用 JustZix:5 秒,而且为该会话里之后访问的每个页面都报告。

使用场景 2 —— 与竞争对手对比

访问一个竞争对手。Output Console 显示它的 LCP/CLS/INP。你的网站 —— 1:1 对比,相同的网络条件、相同的设备。

使用场景 3 —— 开发期间的实时监视器

把一个 Output Console pane 吸附到右侧。启动你的 localhost dev 服务器。每次 F5 → 一条带新鲜 vitals 的 JUSTZIX.log。实时看到你改动的效果(例如懒加载图片 → LCP 上升,布局偏移 → CLS 上升)。

使用场景 4 —— 用 BUTTON 动作导出 JSON

// BUTTON 动作「📊 导出 vitals」
const data = {
  url: location.href,
  timestamp: new Date().toISOString(),
  vitals: window.JZ_LATEST_VITALS || {}
};
const json = JSON.stringify(data, null, 2);
navigator.clipboard.writeText(json);
JUSTZIX.log('Vitals 已导出到剪贴板。');

在 JS 规则里加一行:每次更新后 window.JZ_LATEST_VITALS = vitals;。BUTTON 现在有了当前快照,可导出到文档 / Slack。

接下来做什么

安装 JustZix —— 一个零配置的 Web Vitals 监视器,在用户之前就察觉问题。

为这篇文章评分

暂无评分 — 成为第一个。

自己动手试试

安装 JustZix,粘贴本文中的任意代码片段。两分钟,从零到一条在你所有设备上生效的规则。

获取 JustZix

功能 · 工作原理 · 示例 · 应用场景