Website Performance & Visual Regression Monitor for CI
Pricing
from $19.00 / 1,000 url + viewport auditeds
Website Performance & Visual Regression Monitor for CI
Run local Lighthouse audits, visual screenshot regression tests, DOM/SEO checks, and deterministic CI pass/fail monitoring with persistent baselines. Compare production with staging or monitor websites over time.
Pricing
from $19.00 / 1,000 url + viewport auditeds
Rating
0.0
(0)
Developer
ProdukDigitalAli
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Turn public web pages into a deterministic release gate: visual screenshot diff + bundled local Lighthouse lab scores + DOM/SEO deltas + persistent accepted baselines + machine-readable PASS/REGRESSION output.
This Actor is designed for CI/CD, release validation, scheduled monitoring, and staging-vs-production checks. It does not try to be another generic site crawler.
What you get
For every audited URL/viewport the Actor can return:
BASELINE_CREATED,PASS,REGRESSION,RECOVERED, orERROR- HTTP status and final URL
- visual changed-pixel percentage and a highlighted diff PNG
- current and accepted-baseline screenshots
- Lighthouse category scores from the bundled local provider by default; optional Google PageSpeed provider
- Lighthouse lab LCP, CLS, TBT, FCP, and Speed Index values when available
- score deltas vs the accepted baseline
- title, meta description, canonical, robots, language, H1, and selected DOM text/count changes
- normalized regression reasons and regression types
- a compact run summary in the default key-value store
Metric note: LCP and CLS are Core Web Vitals metrics. TBT is a Lighthouse lab responsiveness diagnostic, not itself a Core Web Vital. This Actor describes these values as Lighthouse lab metrics rather than field-user measurements.
Three high-value use cases
1. Fail a deployment when a key page regresses
Monitor a release candidate and configure limits such as:
- performance score drop > 5 points
- visual difference > 1%
- LCP > 4,000 ms
- CLS > 0.25
- SEO title/canonical/robots changes
Your CI step reads the returned ciPassed boolean and the structured reasons array.
2. Compare staging and production in one run
Use mode: "compare" with a baselineUrl and candidate url. The Actor captures both pages at the same viewport, creates a visual diff, compares SEO/DOM fields and available Lighthouse metrics, and returns one release-gate record.
3. Monitor important pages on a schedule
Use mode: "monitor". The first successful run creates a persistent accepted baseline. Later runs compare against that baseline and can report recovery after a previous regression.
Quick start: monitor a saved baseline
{"targets": [{"url": "https://example.com","label": "homepage"}],"mode": "monitor","device": "desktop","runLighthouse": true,"lighthouseProvider": "local","maxScoreDrop": 5,"maxVisualDiffPercent": 1,"baselineUpdatePolicy": "on_pass","stateNamespace": "production"}
First run:
BASELINE_CREATED
A later healthy run:
PASS
A later threshold violation:
REGRESSION
If the page then returns within the configured thresholds:
RECOVERED
Compare staging vs production
{"targets": [{"url": "https://staging.example.com","baselineUrl": "https://example.com","label": "homepage"}],"mode": "compare","device": "desktop","runLighthouse": true,"lighthouseProvider": "local","maxScoreDrop": 5,"maxVisualDiffPercent": 1,"failOnSeoChanges": true}
compare mode is stateless: the reference and candidate are audited in the same run.
Strict mobile release gate
{"targets": [{"url": "https://example.com","label": "homepage"}],"mode": "monitor","device": "mobile","runLighthouse": true,"lighthouseProvider": "local","requireLighthouse": true,"minPerformanceScore": 80,"minSeoScore": 90,"maxLcpMs": 4000,"maxCls": 0.25,"maxTbtMs": 600,"maxVisualDiffPercent": 1,"failOnSeoChanges": true,"domSelectors": ["main", "h1"],"stateNamespace": "strict-mobile"}
Mobile defaults to a 390x844 Playwright viewport even if the Apify UI materializes the desktop width/height defaults. Explicit custom mobile dimensions are still respected.
Visual-noise controls
Pixel diffs become noisy when pages contain clocks, animated carousels, ad slots, random recommendations, cursors, or live counters. The Actor includes four controls:
- CSS animations and transitions are disabled before capture.
hideSelectorshides elements entirely before screenshot capture.maskSelectorscovers selected elements with a fixed mask color.pixelThresholdignores small per-channel pixel differences.
Example:
{"hideSelectors": [".live-clock", ".ad-slot"],"maskSelectors": ["[data-user-avatar]"],"pixelThreshold": 0.1,"maxVisualDiffPercent": 0.5}
Changing screenshot/DOM normalization settings automatically creates a separate baseline profile, preventing configuration changes from becoming permanent false regressions.
Lighthouse providers
When runLighthouse is enabled, the default provider is local Lighthouse bundled inside the Actor. It launches Lighthouse against the same public URL using the Actor's Chromium runtime, so normal Store users do not need a Google API key.
lighthouseProvider options:
local— default and recommended. Runs bundled Lighthouse inside the Actor.pagespeed— uses Google PageSpeed Insights v5.pagespeedApiKeyis an optional encrypted secret and is never logged.auto— tries local Lighthouse first and falls back to PageSpeed only when a PageSpeed API key is supplied.
requireLighthouse: false allows visual/DOM monitoring to continue if the selected provider is temporarily unavailable. requireLighthouse: true turns provider unavailability into LIGHTHOUSE_UNAVAILABLE and a CI regression.
Provider identity is part of the baseline profile fingerprint. Switching from local Lighthouse to PageSpeed (or changing Lighthouse categories) creates a separate baseline instead of comparing unlike score sources.
Google PageSpeed remains optional because API quota/rate limiting is outside the Actor's control. Cloud staging on 2026-08-30 returned HTTP 429 with a zero keyless daily quota, which is why local Lighthouse is now the publication default.
Regression types
Possible regressionTypes include:
HTTP_ERROR— final page response is HTTP 4xx/5xxPERFORMANCE_REGRESSION— score drop, absolute score threshold, or lab-metric ceiling failedVISUAL_REGRESSION— changed-pixel percentage exceeds the configured maximumSEO_REGRESSION— SEO score or configured SEO field assertions failedDOM_CHANGED— configured DOM assertions changedLIGHTHOUSE_UNAVAILABLE— only a failure whenrequireLighthouseis enabled
Multiple regression types can be returned in the same result.
Baseline semantics
mode: "monitor" stores accepted baselines in the named key-value store:
ci-web-regression-state-v1
baselineUpdatePolicy controls movement of that accepted baseline:
| Policy | Behavior |
|---|---|
on_pass | Default. Update only after PASS or RECOVERED; regressions do not overwrite the accepted baseline. |
never | Keep the original baseline after it is created. |
always | Move the baseline after every completed audit, including a regression. |
An initial run can still return REGRESSION if absolute thresholds, required Lighthouse availability, or HTTP health fail. The capture is stored so a later healthy run can produce RECOVERED.
Use stateNamespace to isolate projects, branches, environments, or clients.
Stable identity rule
If a target has an explicit label, the label is its baseline identity. This lets a stable label such as homepage survive deployment URL changes. If no label is provided, the normalized URL is used instead, so simply reordering an input list cannot attach the wrong saved baseline.
Selected DOM / SEO checks
The Actor always records:
<title>- meta description
- canonical link
- robots meta
<html lang>- up to 10 H1 texts + H1 count
You can additionally track CSS selectors:
{"domSelectors": ["main h1", "[data-testid=pricing]", ".release-version"],"failOnDomChanges": true}
For every selector the Actor stores element count and the first element's normalized text.
Artifacts
The result contains KVS record keys for:
- current screenshot
- accepted/reference baseline screenshot
- visual diff image
The diff PNG highlights changed pixels in red.
emitOnlyFailures
Set:
{"emitOnlyFailures": true}
to suppress PASS and RECOVERED dataset rows while still performing the audit and updating state according to the baseline policy. BASELINE_CREATED, REGRESSION, and ERROR remain visible. The run summary still counts all processed results, not only emitted rows.
Example output
{"recordType": "CI_REGRESSION_RESULT","mode": "monitor","label": "homepage","url": "https://example.com","device": "desktop","status": "REGRESSION","ciPassed": false,"primaryRegressionType": "PERFORMANCE_REGRESSION","httpStatus": 200,"finalUrl": "https://example.com/","performanceScore": 78,"seoScore": 100,"lcpMs": 3210,"cls": 0.05,"tbtMs": 380,"visualDiffPercent": 1.84,"regressionTypes": ["PERFORMANCE_REGRESSION","VISUAL_REGRESSION"],"reasons": ["performance score dropped 9.00 points, above allowed 5.00.","Visual diff 1.8400% exceeds maximum 1.0000%."],"scoreDeltas": {"performance": -9,"accessibility": 0,"bestPractices": 0,"seo": 0},"errorType": null,"errorMessage": null}
CI integration pattern
The Actor deliberately returns a structured ciPassed boolean instead of crashing the Actor run whenever a regression is found. This keeps the evidence dataset and screenshots available. Your pipeline can fail its own release step when any returned row has:
ciPassed == false
or when the run summary has:
ciPassed == false
Safety and target restrictions
This Actor is for public HTTP(S) web pages.
It rejects:
- localhost
- literal private/loopback/link-local/reserved IP targets
- hostnames that resolve to non-public IP addresses at the initial target gate
Use it only on pages you are authorized to test and monitor. Pages behind login/private networks are intentionally out of scope for the September MVP.
Pricing model
The source defines one PPE event:
url-viewport-audited
at an indicative source price of:
$0.0099 per successfully audited URL/viewport
A monitor target records one audit event after successful page capture/evaluation. A compare target audits two pages (reference + candidate) and therefore records two events. Failed captures/invalid targets are not charged by the custom event.
The publication price should be re-checked after Apify Cloud staging confirms real browser/local-Lighthouse cost and margin.
Limitations
- Lighthouse scores are lab measurements and naturally vary. Avoid thresholds so tight that normal lab variance becomes release noise.
- Local Lighthouse is the default to avoid external quota dependencies. If you explicitly select PageSpeed, Google API quota/rate limiting remains outside the Actor's control.
- Pixel comparison is intentionally literal. Dynamic content should be hidden/masked or given an appropriate threshold.
- Full-page screenshots are slower and more sensitive to lazy-loaded/dynamic content than viewport screenshots.
- Logged-in pages, private staging networks, VPN-only services, and local URLs are not supported in this MVP.
- The Actor audits explicitly supplied URLs; it is not a full-domain crawler or broken-link scanner.
API / MCP-friendly design
The input is bounded to 10 targets per run, secrets are encrypted, output field names are stable, and statuses/regression types are explicit. This makes the Actor suitable for Apify API, schedules, OpenAPI/MCP calling surfaces, GitHub/GitLab CI wrappers, Make/Zapier, and internal release tooling.
Recommended task examples
- Fail a deployment when Lighthouse performance drops
- Compare staging and production screenshots automatically
- Monitor Core Web Vitals lab metrics and SEO regressions on key pages
Support checklist
If you report an issue, include:
- public reproduction URL(s)
- monitor vs compare mode
- device/viewport
- thresholds
- noise-control selectors
- whether Lighthouse is required
- Actor run ID
Never include a PageSpeed API key in an issue or log excerpt.