From c2bc5715305d83701ac7e3326c8bb1b90ad806e3 Mon Sep 17 00:00:00 2001 From: Rico Kahler Date: Thu, 26 Sep 2024 11:41:13 -0500 Subject: [PATCH] raf --- perf/efps/helpers/measureFpsForInput.ts | 38 +++++++++++++++++++++++-- perf/efps/runTest.ts | 11 ++++--- perf/efps/tests/article/article.ts | 3 ++ perf/efps/tests/recipe/recipe.ts | 6 +++- perf/efps/tests/synthetic/synthetic.ts | 2 ++ 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/perf/efps/helpers/measureFpsForInput.ts b/perf/efps/helpers/measureFpsForInput.ts index 417cd3f191b5..87a632a1e7db 100644 --- a/perf/efps/helpers/measureFpsForInput.ts +++ b/perf/efps/helpers/measureFpsForInput.ts @@ -1,9 +1,9 @@ -import {type Locator} from 'playwright' +import {type Locator, type Page} from 'playwright' import {type EfpsResult} from '../types' import {calculatePercentile} from './calculatePercentile' -export async function measureFpsForInput(input: Locator): Promise { +export async function measureFpsForInput(input: Locator, page: Page): Promise { await input.waitFor({state: 'visible'}) const characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -49,6 +49,29 @@ export async function measureFpsForInput(input: Locator): Promise { await input.pressSequentially(startingMarker) await new Promise((resolve) => setTimeout(resolve, 500)) + const durationsPromise = page.evaluate(async () => { + const durations: number[] = [] + let last = performance.now() + let done = false + + const handleFrame = () => { + const current = performance.now() + durations.push(current - last) + last = current + + if (done) return + requestAnimationFrame(handleFrame) + } + requestAnimationFrame(handleFrame) + + await new Promise((resolve) => { + window.document.addEventListener('__finish', resolve, {once: true}) + }) + done = true + + return durations + }) + for (const character of characters) { inputEvents.push({character, timestamp: Date.now()}) await input.press(character) @@ -57,7 +80,12 @@ export async function measureFpsForInput(input: Locator): Promise { await input.blur() + await page.evaluate(() => { + window.document.dispatchEvent(new CustomEvent('__finish')) + }) + const renderEvents = await rendersPromise + const durations = await durationsPromise await new Promise((resolve) => setTimeout(resolve, 500)) @@ -78,5 +106,11 @@ export async function measureFpsForInput(input: Locator): Promise { const p75 = Math.min(1000 / calculatePercentile(latencies, 0.75), 100) const p90 = Math.min(1000 / calculatePercentile(latencies, 0.9), 100) + console.log('measureFpsForInput', { + p50: calculatePercentile(durations, 0.5), + p75: calculatePercentile(durations, 0.75), + p90: calculatePercentile(durations, 0.9), + }) + return {p50, p75, p90, latencies} } diff --git a/perf/efps/runTest.ts b/perf/efps/runTest.ts index 8367048a5cde..455c5c3e8372 100644 --- a/perf/efps/runTest.ts +++ b/perf/efps/runTest.ts @@ -136,9 +136,9 @@ export async function runTest({ last = current if (done) return - setTimeout(handleFrame, 0) + requestAnimationFrame(handleFrame) } - setTimeout(handleFrame, 0) + requestAnimationFrame(handleFrame) await new Promise((resolve) => { window.document.addEventListener('__finish', resolve, {once: true}) @@ -156,8 +156,11 @@ export async function runTest({ log('Saving results…') const durations = await durationsPromise - calculatePercentile(durations, 0.5) - console.log({frameDuration: calculatePercentile(durations, 0.5)}) + console.log('overall for fixture', { + p50: calculatePercentile(durations, 0.5), + p75: calculatePercentile(durations, 0.75), + p90: calculatePercentile(durations, 0.9), + }) const results = Array.isArray(result) ? result : [result] // const {profile} = await cdp.send('Profiler.stop') diff --git a/perf/efps/tests/article/article.ts b/perf/efps/tests/article/article.ts index f99cdde3b3fd..0e46b0c2c89a 100644 --- a/perf/efps/tests/article/article.ts +++ b/perf/efps/tests/article/article.ts @@ -146,6 +146,7 @@ export default defineEfpsTest({ label: 'title', ...(await measureFpsForInput( page.locator('[data-testid="field-title"] input[type="text"]'), + page, )), }, { @@ -156,12 +157,14 @@ export default defineEfpsTest({ label: 'string in object', ...(await measureFpsForInput( page.locator('[data-testid="field-seo.metaTitle"] input[type="text"]'), + page, )), }, { label: 'string in array', ...(await measureFpsForInput( page.locator('[data-testid="field-tags"] input[type="text"]').first(), + page, )), }, ] diff --git a/perf/efps/tests/recipe/recipe.ts b/perf/efps/tests/recipe/recipe.ts index 3c9f8e4c230f..dd3658e4cbc3 100644 --- a/perf/efps/tests/recipe/recipe.ts +++ b/perf/efps/tests/recipe/recipe.ts @@ -166,11 +166,15 @@ export default defineEfpsTest({ label: 'name', ...(await measureFpsForInput( page.locator('[data-testid="field-name"] input[type="text"]'), + page, )), }, { label: 'description', - ...(await measureFpsForInput(page.locator('[data-testid="field-description"] textarea'))), + ...(await measureFpsForInput( + page.locator('[data-testid="field-description"] textarea'), + page, + )), }, { label: 'instructions', diff --git a/perf/efps/tests/synthetic/synthetic.ts b/perf/efps/tests/synthetic/synthetic.ts index 2ed731428b84..5d1e0271415f 100644 --- a/perf/efps/tests/synthetic/synthetic.ts +++ b/perf/efps/tests/synthetic/synthetic.ts @@ -126,12 +126,14 @@ export default defineEfpsTest({ label: 'title', ...(await measureFpsForInput( page.locator('[data-testid="field-title"] input[type="text"]'), + page, )), }, { label: 'string in object', ...(await measureFpsForInput( page.locator('[data-testid="field-syntheticObject.name"] input[type="text"]'), + page, )), }, ]