计算首屏时间的几种方式
性能监控工具 :性能监控工具如 Google Chrome
的开发者工具( Performance
面板)、Lighthouse
等提供了详细的性能分析和首屏渲染时间的度量。
Navigation Timing API :使用浏览器提供的 Navigation Timing API
来获取有关页面加载和渲染的性能数据。
js
const performanceData = window.performance.timing;
const fcpTime = performanceData.msFirstPaint; // 首次绘制时间
console.log(`FCP 时间:${fcpTime}ms`);
标准的 paint
事件 :通过添加事件监听器来监听paint
事件,然后捕获FCP事件。
js
window.addEventListener('paint', (event) => {
if (event.name === 'first-contentful-paint') {
console.log(`FCP 时间:${event.startTime}ms`);
}
});
PerformanceObserver API:监视各种性能事件。
PerformanceObserver
PerformanceObserver 可用于获取性能相关的数据,例如首帧fp 、首屏fcp 、首次有意义的绘制 fmp等。
PerformanceObserver()
创建并返回一个新的 PerformanceObserver
对象。
提供的方法
PerformanceObserver.observe()
:当记录的性能指标在指定的 entryTypes
之中时,将调用性能观察器的回调函数。
entryTypes 取值:longtask、frame、navigation、resource、mark、measure、paint
PerformanceObserver.disconnect()
:停止性能观察者回调接收到性能指标。
PerformanceObserver.takeRecords()
:返回存储在性能观察器中的性能指标的列表,并将其清空。
FP和FCP的关系
First Paint(FP):是指在浏览器首次将像素呈现在屏幕上的时间点,它不一定代表页面内容的可用性。
First Contentful Paint(FCP):是指在浏览器首次呈现页面的内容,即首次绘制任何文本、图像或其他内容的时间点,考虑了页面上的第一个可见内容,因此它通常在 FP 后发生,但它更关注用户体验。
useFirstContentfulPaint
js
import { useEffect } from 'react';
function useFirstContentfulPaint() {
useEffect(() => {
const observer = new PerformanceObserver(list => {
const entries = list.getEntries();
for (const entry of entries) {
if (entry.name === 'first-contentful-paint') {
console.log(`First Contentful Paint: ${entry.startTime}ms`);
}
}
});
observer.observe({ type: 'paint', buffered: true });
return () => observer.disconnect();
}, []);
return null;
}
export default useFirstContentfulPaint;
js
import { onMounted, onBeforeUnmount } from 'vue';
export default function useFirstContentfulPaint() {
const observer = new PerformanceObserver(list => {
const entries = list.getEntries();
for (const entry of entries) {
if (entry.name === 'first-contentful-paint') {
console.log(`First Contentful Paint: ${entry.startTime}ms`);
}
}
});
onMounted(() => {
observer.observe({ type: 'paint', buffered: true });
});
onBeforeUnmount(() => {
observer.disconnect();
});
return null;
}