Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the ability to work with Performance CDP API #4204

Open
ankur22 opened this issue Nov 8, 2024 · 1 comment
Open

Adding the ability to work with Performance CDP API #4204

ankur22 opened this issue Nov 8, 2024 · 1 comment

Comments

@ankur22
Copy link
Contributor

ankur22 commented Nov 8, 2024

Feature Description

A question that is being asked more frequently is how does my website or component affect the web browser (chrome)? So what metrics can we bring about from chrome to show the end user?

Suggested Solution (optional)

Fortunately there is CDP API that can perform this action, which is the performance API. It works by:

  1. Calling Performance.enable
  2. Running the some k6 browser APIs
  3. Calling either Performance.getMetrics to retrieve the metrics
  4. Or calling Performance.disable to end it.

This will result in the following:

[
  { name: 'Timestamp', value: 139939.973695 },
  { name: 'AudioHandlers', value: 0 },
  { name: 'AudioWorkletProcessors', value: 0 },
  { name: 'Documents', value: 4 },
  { name: 'Frames', value: 1 },
  { name: 'JSEventListeners', value: 51 },
  { name: 'LayoutObjects', value: 1712 },
  { name: 'MediaKeySessions', value: 0 },
  { name: 'MediaKeys', value: 0 },
  { name: 'Nodes', value: 1845 },
  { name: 'Resources', value: 4 },
  { name: 'ContextLifecycleStateObservers', value: 19 },
  { name: 'V8PerContextDatas', value: 6 },
  { name: 'WorkerGlobalScopes', value: 0 },
  { name: 'UACSSResources', value: 0 },
  { name: 'RTCPeerConnections', value: 0 },
  { name: 'ResourceFetchers', value: 4 },
  { name: 'AdSubframes', value: 0 },
  { name: 'DetachedScriptStates', value: 4 },
  { name: 'ArrayBufferContents', value: 0 },
  { name: 'LayoutCount', value: 3 },
  { name: 'RecalcStyleCount', value: 7 },
  { name: 'LayoutDuration', value: 0.019831 },
  { name: 'RecalcStyleDuration', value: 0.005009 },
  { name: 'DevToolsCommandDuration', value: 0.009659 },
  { name: 'ScriptDuration', value: 0.012199 },
  { name: 'V8CompileDuration', value: 0.000039 },
  { name: 'TaskDuration', value: 0.083739 },
  { name: 'TaskOtherDuration', value: 0.037002 },
  { name: 'ThreadTime', value: 0.067871 },
  { name: 'ProcessTime', value: 0.192818 },
  { name: 'JSHeapUsedSize', value: 2970160 },
  { name: 'JSHeapTotalSize', value: 5275648 },
  { name: 'FirstMeaningfulPaint', value: 0 },
  { name: 'DomContentLoaded', value: 139939.96493 },
  { name: 'NavigationStart', value: 139939.854245 }
]

Here's a PW script that can be used to test this:

// @ts-check
import { test, chromium } from '@playwright/test';

test('nav_to_test.k6.io', async () => {
  const browser = await chromium.launch()
  const context = await browser.newContext()
  const page = await context.newPage()

  const client = await page.context().newCDPSession(page);
  client.send('Performance.enable');
  
  await page.goto('https://test.k6.io', {waitUntil: 'networkidle'});
  // Requires some interaction to bring about INP and FID Web Vitals
  await page.locator('a[href="/news.php"]').click();

  const result = await client.send('Performance.getMetrics');
  console.log(result.metrics);

  await page.close({ runBeforeUnload: true })

  await browser.close()
});

In Playwright, there ins't a dedicated API to perform such an action, instead they allow the use of CDPSession which can be used to run raw CDP requests. It's not clear what the security implications are of opening up a CDPSession like this.

In Puppeteer there is page.metrics.

The options for us are:

  1. Create a dedicated API to retrieve these performance metrics, basically a wrapper around the Performance CDP API.
  2. Implement CDPSession but only allow some of the API calls (e.g. only the Performance ones) to be made through it until it's clear what security implications it may have.

Already existing or connected issues / PRs (optional)

#4427

@ankur22 ankur22 added the feature label Nov 8, 2024
@ankur22 ankur22 transferred this issue from grafana/xk6-browser Jan 21, 2025
@bubafinder
Copy link

Would it be possible to create a K6 wrapper around Playwright and the Chromium Performance API, allowing the generated performance metrics to be integrated into the K6 ecosystem?

This way, instead of developing xk6-browser, K6 could leverage Playwright as the browser test runner and use the Performance API metrics to provide performance insights.

I’m not sure if there are any limitations—just throwing the idea out there. We have a lot of Playwright smoke tests and are still exploring how to replace K6 browser tests with them since K6 browser tests are harder to write and less stable.

If a wrapper is possible, it could enable a better hybrid testing approach: using K6 API tests to generate load on the server while leveraging Playwright smoke tests to capture browser performance metrics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants