feat: create MobilePerformanceMonitor base structure
This commit is contained in:
@@ -1,6 +1,4 @@
|
|||||||
import { Page } from '@playwright/test';
|
import { Page } from '@playwright/test';
|
||||||
import lighthouse from 'lighthouse';
|
|
||||||
import * as chromeLauncher from 'chrome-launcher';
|
|
||||||
|
|
||||||
export interface CoreWebVitals {
|
export interface CoreWebVitals {
|
||||||
FCP: number;
|
FCP: number;
|
||||||
@@ -17,64 +15,4 @@ export interface LighthouseResult {
|
|||||||
|
|
||||||
export class MobilePerformanceMonitor {
|
export class MobilePerformanceMonitor {
|
||||||
constructor(private page: Page) {}
|
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,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async runLighthouseAudit(url: string): Promise<LighthouseResult> {
|
|
||||||
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] });
|
|
||||||
const options = {
|
|
||||||
logLevel: 'info' as const,
|
|
||||||
output: 'json' as const,
|
|
||||||
onlyCategories: ['performance'],
|
|
||||||
port: chrome.port,
|
|
||||||
};
|
|
||||||
|
|
||||||
const runnerResult = await lighthouse(url, options);
|
|
||||||
await chrome.kill();
|
|
||||||
|
|
||||||
if (!runnerResult) {
|
|
||||||
throw new Error('Lighthouse audit failed');
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
score: runnerResult.lhr.categories.performance.score * 100,
|
|
||||||
audits: runnerResult.lhr.audits,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user