PerformanceObserver 是监控页面加载性能最可靠方式,必须在<head>顶部初始化以捕获 FCP、LCP 等渲染指标,避免依赖失真的 DOMContentLoaded 或 load 事件。

直接用 PerformanceObserver 监听 navigation 和 paint 类型,是当前最可靠、最贴近用户真实感知的页面加载性能监控方式。靠 DOMContentLoaded 或 load 事件已严重失真,尤其在 SPA 和 SSR 场景下基本不可信。
FCP 和 LCP 必须用 PerformanceObserver 订阅,不能等页面加载完再查
浏览器只在首次绘制发生时触发 first-contentful-paint 和 largest-contentful-paint 事件,错过初始化时机就永远拿不到——performance.getEntriesByType('paint') 或 performance.getEntriesByType('largest-contentful-paint') 在 DOM 加载后调用大概率返回空数组。
- 必须把
PerformanceObserver初始化代码放在<head>最顶部,越早越好(甚至可内联) -
entryTypes: ['paint']只能捕获 FP/FCP;LCP 需额外加['largest-contentful-paint'] - SPA 路由跳转不会触发新
navigation记录,但会触发新的paint和largest-contentful-paint,需注意监听生命周期
TTFB 不是 responseStart - requestStart 就完事
这个差值在真实用户场景(RUM)里常被 CDN 缓存、HTTP/2 多路复用、SSR 模板渲染干扰,导致数值偏高或含义模糊。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
- 若页面走 SSR,
requestStart到responseStart包含服务端模板耗时,不是纯网络延迟 - HTTP/2 下浏览器可能合并多个请求的
requestStart,造成 TTFB 虚高 - 建议同时采集
connectEnd和secureConnectionStart,判断是否卡在 TLS 握手(iOS WebKit 对 OCSP stapling 敏感) - 更稳妥的做法:用
navigation.timing.responseStart - navigation.timing.fetchStart作为“首字节网络耗时”,排除 DNS 和连接建立干扰
不要依赖 DOMContentLoaded 或 load 事件做首屏判断
这两个事件在现代前端中已严重偏离用户可见性:前者等待所有同步脚本执行完毕(包括 JS 动态插入 DOM),后者强制等全部图片、iframe 加载完成,和“用户看到内容”几乎无关。
立即学习“前端免费学习笔记(深入)”;
-
DOMContentLoaded在 JS 执行完document.createElement+appendChild后才触发,SPA 首屏内容全是 JS 渲染的,此时 FCP 可能早已发生 -
load会被懒加载图片、第三方广告 iframe 拖慢数秒,完全不能代表首屏体验 - FP/FCP/LCP 全部基于渲染流水线,不依赖资源加载完成,才是用户真正“看见”的时间点
真正难的不是采集数据,而是区分哪些指标反映的是网络链路、哪些反映的是渲染管线、哪些又被框架层掩盖了。比如 LCP 元素在 React 中可能由 useEffect 触发渲染,它的时间戳背后混着 JS 执行、diff、commit、layout、paint 多个阶段——单看一个数字,容易误判优化方向。


















