56 lines
1.5 KiB
TypeScript
56 lines
1.5 KiB
TypeScript
import { Page } from '@playwright/test';
|
|
|
|
export interface CoreWebVitals {
|
|
FCP: number;
|
|
LCP: number;
|
|
CLS: number;
|
|
FID: number;
|
|
TTI: number;
|
|
}
|
|
|
|
export interface LighthouseResult {
|
|
score: number;
|
|
audits: Record<string, any>;
|
|
}
|
|
|
|
export class MobilePerformanceMonitor {
|
|
constructor(private page: Page) {}
|
|
|
|
async getCoreWebVitals(): Promise<CoreWebVitals> {
|
|
const vitals = await this.page.evaluate(() => {
|
|
return new Promise((resolve) => {
|
|
const metrics: any = {};
|
|
|
|
const observer = new PerformanceObserver((list) => {
|
|
for (const entry of list.getEntries()) {
|
|
if (entry.entryType === 'paint') {
|
|
if (entry.name === 'first-contentful-paint') {
|
|
metrics.FCP = entry.startTime;
|
|
}
|
|
} else if (entry.entryType === 'largest-contentful-paint') {
|
|
metrics.LCP = entry.startTime;
|
|
} else if (entry.entryType === 'layout-shift') {
|
|
if (!metrics.CLS) metrics.CLS = 0;
|
|
metrics.CLS += (entry as any).value;
|
|
}
|
|
}
|
|
});
|
|
|
|
observer.observe({ entryTypes: ['paint', 'largest-contentful-paint', 'layout-shift'] });
|
|
|
|
setTimeout(() => {
|
|
observer.disconnect();
|
|
resolve(metrics);
|
|
}, 5000);
|
|
});
|
|
});
|
|
|
|
return {
|
|
FCP: vitals.FCP || 0,
|
|
LCP: vitals.LCP || 0,
|
|
CLS: vitals.CLS || 0,
|
|
FID: 0,
|
|
TTI: 0,
|
|
};
|
|
}
|
|
} |