# Website Performance Analyzer — Speed Test & Core Web Vitals (`scrapeworks/website-performance-analyzer`) Actor

Test website speed for any list of URLs: TTFB, load time, page weight, compression, redirects, caching and security headers — with a transparent 0-100 score and findings. Optionally adds the Google Lighthouse score and Core Web Vitals (FCP, LCP, CLS, TBT) via PageSpeed Insights.

- **URL**: https://apify.com/scrapeworks/website-performance-analyzer.md
- **Developed by:** [Nicolas van Arkens](https://apify.com/scrapeworks) (community)
- **Categories:** SEO tools, Developer tools
- **Stats:** 13 total users, 2 monthly users, 93.1% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Website Performance Analyzer — Speed Test & Core Web Vitals

Test the performance of any list of websites in one run. For every URL this actor measures **real server response time (TTFB), full load time, page weight, compression, HTTP version, redirects, resource counts, caching and security headers** — and turns them into a transparent **0–100 performance score with a graded A–F rating and the exact reason for every lost point**.

Optionally, each URL is also run through the **official Google PageSpeed Insights API**, adding the **Lighthouse performance score**, lab metrics (**FCP, LCP, CLS, TBT, Speed Index**) and **real-user Core Web Vitals field data** from the Chrome UX Report.

Perfect for agencies auditing client sites, SEO monitoring, competitor benchmarking, and bulk performance checks across hundreds of URLs — no browser, no setup, results as a clean dataset you can export to JSON, CSV, or Excel.

### What data you get

| Field | Description |
|---|---|
| `url` / `finalUrl` | The URL you asked for and where it ended up after redirects |
| `performanceScore` | Transparent 0–100 score from direct measurements |
| `grade` | A–F rating (A ≥ 90, B ≥ 80, C ≥ 70, D ≥ 55, F below) |
| `findings` | Human-readable list of every issue that cost points |
| `ttfbMs` | Time to first byte — real server response time in ms |
| `totalTimeMs` | Time to download the full document in ms |
| `htmlBytes` | Document size (decoded) |
| `httpVersion` | HTTP/1.1, HTTP/2 … (HTTP/1.1 is flagged) |
| `redirects` | Number of redirect hops before the final URL |
| `contentEncoding` | Compression in use (gzip / br) — missing compression is flagged |
| `resources` | Counts of scripts, external scripts, stylesheets, images, iframes, approximate DOM size, viewport meta presence |
| `caching` | Cache-Control, ETag, Last-Modified, Expires headers |
| `securityHeaders` | Presence of HSTS, CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy |
| `server` | Server header (e.g. cloudflare, nginx) |
| `pagespeed` | Optional Google Lighthouse score, lab metrics (FCP/LCP/CLS/TBT/Speed Index) and Core Web Vitals field data |

### Input

```json
{
    "urls": ["https://example.com", "https://www.wikipedia.org"],
    "strategy": "mobile",
    "runPagespeed": true
}
```

- **urls** — one URL per line; bare domains work too (`https://` is added).
- **strategy** — `mobile` or `desktop`, used for the Lighthouse run.
- **runPagespeed** — set `false` to skip Google and rely on direct measurements only (faster).
- **googleApiKey** — optional, free ([get one here](https://developers.google.com/speed/docs/insights/v5/get-started), 25,000 requests/day). Without a key the Lighthouse part uses Google's shared anonymous quota, which is often busy — the direct measurements always work regardless.

### Output sample (real run)

```json
{
  "url": "https://example.com",
  "finalUrl": "https://example.com",
  "success": true,
  "statusCode": 200,
  "performanceScore": 98,
  "grade": "A",
  "findings": [
    "Missing Strict-Transport-Security header"
  ],
  "ttfbMs": 181,
  "totalTimeMs": 181,
  "htmlBytes": 559,
  "httpVersion": "HTTP/2",
  "redirects": 0,
  "contentType": "text/html",
  "contentEncoding": "br",
  "resources": {
    "scripts": 0,
    "externalScripts": 0,
    "stylesheets": 0,
    "images": 0,
    "iframes": 0,
    "domNodesApprox": 12,
    "hasViewportMeta": true
  },
  "caching": {
    "cacheControl": null,
    "etag": null,
    "lastModified": "Tue, 09 Jun 2026 21:01:00 GMT",
    "expires": null
  },
  "securityHeaders": {
    "strict-transport-security": false,
    "content-security-policy": false,
    "x-content-type-options": false,
    "x-frame-options": false,
    "referrer-policy": false,
    "permissions-policy": false
  },
  "server": "cloudflare"
}
```

A slow page looks like this instead (`nytimes.com`, mobile): score **69 (D)** with findings such as *"33 external scripts referenced (target < 15)"*, *"Very large DOM (~4100 nodes)"*, and *"One redirect before the final URL"*.

### Use cases

- **Agency site audits** — run a client's whole sitemap through it and hand over a prioritized findings list per page.
- **Competitor benchmarking** — score your site against competitors on identical, objective measurements.
- **Continuous monitoring** — schedule it on Apify and diff scores week over week; integrate with Make/Zapier/webhooks.
- **Pre-launch checks** — catch missing compression, redirect chains, HTTP/1.1, missing caching or security headers before going live.

### FAQ

**How is the 0–100 score computed?** It starts at 100 and deducts points for measurable issues (slow TTFB, missing compression, heavy HTML, HTTP/1.1, redirect chains, excessive scripts/images/DOM size, missing viewport/caching/HSTS). Every deduction appears in `findings`, so the score is fully explainable — no black box.

**Is this the same as Lighthouse?** The direct score is its own measurement of server- and document-level performance. If you enable `runPagespeed`, you also get the official Google Lighthouse score and Core Web Vitals alongside it.

**Do I need a Google API key?** No — but Lighthouse enrichment is much more reliable with one (it's free). Without a key, the actor shares Google's anonymous quota with everyone else; when that quota is busy you still get all direct measurements.

**Does it render JavaScript?** No — that's why it's fast and cheap. Rendering metrics (LCP, CLS, TBT) come from the optional Lighthouse integration instead.

**What happens with unreachable URLs?** They produce an error row (`success: false`) with the reason, and you are **not charged** for them — you pay only for successful results.

**How is it priced?** Pay per event: a small fee per successfully analyzed URL. Failed URLs are free.

# Actor input Schema

## `urls` (type: `array`):

One website URL per line (e.g. https://example.com). The scheme is optional — bare domains get https:// added automatically. Each URL produces one result row.

## `strategy` (type: `string`):

Which device profile Google PageSpeed Insights should simulate for the Lighthouse score and lab metrics. Has no effect on the direct measurements.

## `runPagespeed` (type: `boolean`):

If enabled, each URL is also run through the official Google PageSpeed Insights API to get the Lighthouse performance score, lab metrics (FCP, LCP, CLS, TBT, Speed Index) and real-user Core Web Vitals field data. Works without a key on Google's small shared quota; for reliable high-volume runs supply a free Google API key below. If the quota is exhausted the actor still returns all direct measurements.

## `googleApiKey` (type: `string`):

Optional API key for the PageSpeed Insights API — get one free at https://developers.google.com/speed/docs/insights/v5/get-started (25,000 requests/day). Without a key, Lighthouse enrichment uses Google's shared anonymous quota, which is often exhausted; direct measurements are unaffected either way.

## Actor input object example

```json
{
  "urls": [
    "https://example.com",
    "https://www.wikipedia.org"
  ],
  "strategy": "mobile",
  "runPagespeed": true
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://example.com",
        "https://www.wikipedia.org"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapeworks/website-performance-analyzer").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": [
        "https://example.com",
        "https://www.wikipedia.org",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("scrapeworks/website-performance-analyzer").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://example.com",
    "https://www.wikipedia.org"
  ]
}' |
apify call scrapeworks/website-performance-analyzer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapeworks/website-performance-analyzer"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/y8f7LpIl5RPIM4eP4/builds/0MGAibqvKFjcB3RSw/openapi.json
