This write-up condenses the published DEV tutorial “Browser-based performance testing with K6” into an actionable walkthrough for frontend teams.

Why k6 browser

  • Simulates real browser interactions (Chromium) vs. protocol-only tests.
  • Captures Web Vitals (LCP/INP/CLS) and UX signals (spinners, interactivity).
  • Reuses familiar k6 scripting with async/await + locators.

Setup

  1. Install k6 (latest) and ensure Node/npm are available.
  2. Project skeleton:
k6-tests/
  libs/      # flows (login, add to cart, checkout)
  pages/     # Page Object Model classes
  tests/     # test entry scripts
  utils/     # shared options (browser config, VUs, iterations)
  1. Configure browser scenario (utils/k6-options.js):
export const browserOptions = {
  scenarios: {
    ui: {
      executor: "shared-iterations",
      vus: 1,
      iterations: 15,
      options: { browser: { type: "chromium" } },
    },
  },
};

Example flow (simplified)

import { browser } from "k6/browser";
import { check } from "k6";

export const options = browserOptions;

export default async function () {
  const page = await browser.newPage();
  await page.goto("https://www.saucedemo.com/");
  await page.locator("#user-name").type("standard_user");
  await page.locator("#password").type("secret_sauce");
  await page.locator("#login-button").click();
  check(page, { "login ok": () => page.locator(".title").textContent() === "Products" });
  await page.close();
}

Running & reporting

  • CLI run: k6 run ./tests/buyItemsUserA.js
  • Live dashboard: K6_WEB_DASHBOARD=true K6_WEB_DASHBOARD_OPEN=true k6 run ...
  • Export HTML report: K6_WEB_DASHBOARD=true K6_WEB_DASHBOARD_EXPORT=results/report.html

Metrics to watch (aligns to Core Web Vitals)

  • browser_web_vital_lcp — largest content paint; target < 2.5s p75.
  • browser_web_vital_inp — interaction to next paint; target < 200ms p75.
  • browser_web_vital_cls — layout shift; target < 0.1.
  • Add custom checks for “spinner disappears”, “cart count”, “success message”.

Tips

  • Keep tests short and focused; one scenario per file.
  • Reuse Page Objects for maintainability.
  • Run with realistic VUs/iterations that mirror expected traffic.
  • Use screenshots on failure for debuggability (page.screenshot()).

Takeaway: k6 browser mode gives frontend teams reproducible, scriptable UX performance checks—ideal for catching regressions before they reach real users.