Spitfire

Version: 0.31.0This documentation is for Spitfire 0.31.0.

Browser step (Web Vitals)

The Browser step takes a user journey in a real browser (headless Chromium) and measures what the user sees: LCP (largest content shown), CLS (layout shift), INP (response to a click), TTFB and load time. The aim is not to generate load with browsers; while the protocol load (HTTP, gRPC…) pushes the system, a few browser VUs answer "what does the user see under load?".

When to use it

  • To see whether pages really slow down during a load test, and how much the front end (JavaScript, images, third-party scripts) suffers apart from the API.
  • To catch Web Vitals regressions after a release in CI with a threshold (browser_lcp p(90)<2500).

Runner requirement

The browser step needs a runner with Chromium: the algebransoft/spitfire:<version>-browser image. In Runners → Add a runner → the Docker tab, tick For browser steps; the command then uses that image. Such a runner labels itself browser: chromium, and Spitfire gives runs with browser steps only to those runners. Without enough browser runners the run does not start and says why. On runners without Docker that have Chromium installed, give its path in SPITFIRE_CHROME.

Capacity: a browser VU is expensive: on a real page about 350 MB of memory and ~20% of a core per VU. A 4 vCPU / 8 GB runner carries about 10 browser VUs. Giving the protocol load to other runners makes the measurement more reliable.

Adding a step

  1. Add step → Protocol: Browser.
  2. Add the actions in order; the first must be Open the page:
    • Open the page (URL; waits for the load event)
    • Click (a CSS selector; waits until the element is visible)
    • Type (selector and text; {{variables}} work)
    • Wait until visible (selector)
    • Check the text (text; the whole page when the selector is empty) — the step fails when the text does not come in time
    • Pause (reading) (a duration)
  3. Every action has a timeout (30s by default).

Every VU has its own tab and cookies (like a private window); the session is kept across steps and iterations. Checks see the page's text: Body contains verifies a text like "Your order is placed".

json
{"id": "buy", "name": "Buy", "protocol": "browser",
 "browser": {"actions": [
   {"do": "goto", "url": "{{base}}/cart"},
   {"do": "type", "selector": "#email", "text": "{{email}}"},
   {"do": "click", "selector": "button[type=submit]"},
   {"do": "expect", "text": "Your order is placed", "timeout": "10s"}]}}

Metrics it produces

Metric Meaning
req_duration The whole journey (all actions)
browser_lcp The last page's Largest Contentful Paint (ms)
browser_cls The last page's Cumulative Layout Shift (unitless)
browser_inp The step's longest interaction (Interaction to Next Paint, ms)
browser_ttfb, browser_load First byte and load event (ms)
browser_lag How late the runner's own timer fires (ms): how busy the runner is

The Browser card on the run page colours each step's p90 values with Google's thresholds (LCP ≤ 2.5 s good, > 4 s poor; INP ≤ 200 ms good, > 500 ms poor; CLS ≤ 0.1 good, > 0.25 poor).

Reliability: when a runner is saturated, browser numbers look worse than they are. When browser_lag p95 passes 100 ms the card warns: use fewer browser VUs or give browser steps their own runner.

Mind Chrome's definitions: user input (a click, typing) stops LCP, and shifts within 500 ms after input do not count toward CLS. Low-content images (a flat colour) are not LCP candidates.

License

At most, per run: 1 browser VU on the free edition, 5 on the Growth plans, 20 on Scale; no limit on Enterprise. What counts are the VUs of scenarios with a browser step.

Common problems

Symptom: A run does not start: "browser steps need runners with a browser". Cause: The chosen or idle runners have no browser. Fix: Add a runner with the -browser image; the Runners page shows its browser label.

Symptom: Browser numbers vary a lot between runs, and the card says the runner was busy. Cause: The runner's CPU is not enough. Fix: Use fewer browser VUs, a bigger runner, or give the protocol load to other runners.