Browser-side performance testing for the ShopLite demo storefront. A real Chrome walks the checkout funnel — catalog → product → cart → checkout — while sitespeed.io captures Core Web Vitals and visual metrics for every page, writes an HTML report, and streams the numbers to InfluxDB → Grafana for a live dashboard.
This is the frontend companion to the ShopLite load-testing series (JMeter / k6 / Locust / Gatling) — same shop, different question: not "how many requests can the backend take?" but "how fast does the page actually feel?"
💡 The script is the easy part. Driving a browser through a checkout is a few lines. The real work is making the run reproducible, picking metrics that map to user experience (LCP, CLS, Speed Index — not just "page load"), pinning network conditions so numbers are comparable, and turning a pile of runs into a dashboard someone will actually look at. That plumbing is what this repo is about.
Note. This is a personal portfolio project — a from-scratch reconstruction built entirely on public tools (sitespeed.io, InfluxDB, Grafana) against a fictional storefront. It is not affiliated with, and contains no material from, any employer or client.
| Path | What it is |
|---|---|
mock/ |
The system under test — a static ShopLite storefront served by nginx |
sitespeed/scripts/shop-journey.js |
The funnel journey (catalog → product → add-to-cart → cart → checkout) |
sitespeed/shared/helpers.js |
Reusable measurement wrappers (navigate-and-measure, click-and-measure) |
sitespeed/config/shoplite.json |
Browser, iterations, connectivity, metric filter, InfluxDB target |
grafana/ |
Provisioned datasource + Core Web Vitals dashboard |
docker-compose.yml |
The whole stack: mock + influxdb + grafana + sitespeed |
docs/ |
Test approach and project brief |
No Node, no Chrome, no setup — just Docker.
# One-shot run (CI style): builds, runs the journey, tears down when done.
docker compose up --build --abort-on-container-exit
# Live mode: keep InfluxDB + Grafana up so you can watch the dashboard.
docker compose up --buildThen open:
- HTML report —
results/(newest folder) → openindex.html - Live dashboard — http://localhost:3000 (anonymous viewer enabled)
- Storefront under test — http://localhost:8080
Tune the run in sitespeed/config/shoplite.json:
browsertime.iterations (samples per page), browsertime.connectivity.profile
(cable, 3g, 4g, native), and browsertime.browser (chrome / firefox).
The four funnel pages, rendered and captured by Chrome during the run:
sitespeed.io renders a full HTML report per run — per-page Core Web Vitals, filmstrips, waterfalls, CPU, and a coach score:
Every run streams metrics to InfluxDB over the Graphite protocol; the provisioned Grafana dashboard makes Core Web Vitals the hero:
- CWV gauges scored against Google's thresholds (LCP ≤2.5s, CLS ≤0.1, TBT ≤200ms, FCP ≤1.8s, Speed Index ≤3.4s, FID ≤100ms) with green/amber/red bands.
- Per-page summary table — every page × every key metric, each cell coloured by the same thresholds, so a regression on any page jumps out.
- Trends per page for CWV and the page-timing breakdown, plus a run-health row.
- Dynamic
category / group / page / browser / connectivityfilters.
- Metrics that map to experience. The dashboard focuses on Core Web Vitals and visual metrics — First/Largest Contentful Paint, Cumulative Layout Shift, Speed Index, Visual Complete — which the InfluxDB templates promote to clean, named measurements. "Load time" alone hides how a page feels.
- Comparable runs. Network is pinned via a connectivity profile and each page is sampled several times so a single noisy run doesn't skew the picture.
- Self-contained. The storefront is a static mock baked into its own image — the suite needs no external site and runs the same on a laptop or in CI.
- How metrics flow. sitespeed.io has no native InfluxDB output — it speaks the
Graphite line protocol, so InfluxDB 1.8 ingests on its Graphite listener (
:2003) and a template (influxdb/influxdb.conf) maps each metric path to a measurement and tags (page,group,browser,connectivity,category). - Local demo, not production. The stack is meant to run on a laptop or in CI.
InfluxDB runs unauthenticated and Grafana ships with
admin/adminand anonymous viewing — fine for a throwaway local demo, but do not expose it as-is. There are no real secrets anywhere in this repo.
The same ShopLite journey (browse → add-to-cart → checkout) is covered across the portfolio — five backend load-testing tools plus this frontend Core Web Vitals one — each a one-command Dockerized demo:
| Tool | Language / DSL | SLOs as | Report | Repo |
|---|---|---|---|---|
| Apache JMeter | XML + Groovy | Assertions | HTML dashboard | ShopLite-load-tests |
| Grafana k6 | JavaScript | Thresholds | HTML report | ShopLite-load-tests-k6 |
| Locust | Python | Code-level checks | Built-in HTML | ShopLite-load-tests-locust |
| Gatling | Scala DSL | Assertions | HTML charts | ShopLite-load-tests-gatling-scala |
| Gatling | Java DSL | Assertions | HTML charts | ShopLite-load-tests-gatling-javaDSL |
| sitespeed.io | JavaScript | Budgets | HTML + Grafana | ShopLite-ui-perf (this repo) |
| Observability | InfluxDB + Grafana | — | Live dashboards | ShopLite-observability |
Sample failure report — red dashboards + a short analysis of one deliberately broken run (errors, KO, slow Core Web Vitals): ShopLite-observability/reports.
MIT © Sergiy Cherednychenko


