Free full report, no signup

Find what is slowing your website.
Down to the file. What to fix first.

Paste your website address. Free speed score, the slow file, and what to fix first.

Measure as
Don't want to wait here? Have it emailed

Type it in, then press Check my site as normal. One email when the scan finishes, nothing else ever. Use an address you own. Gmail may file the first one under Promotions.

Free. We only read your site. Nothing changes.

Or see how it works first

Public reports

Sites people checked.

Open any report. Same free answer you get when you paste a site.

One report per site. Anyone with the link can open it.

The problem

Most speed reports list things that do not raise your score.

You open a long list. Almost none of it adds to the score. Nothing says which items would actually help.

5 of 49

Items in a typical speed report that add to the score. The other 44 are tips. Nothing says which tip would move one of the five.

0 of 25

What one real site already scored on the part its whole image fix list pointed at. Doing all of those fixes would have earned almost nothing.

9

Points between two checks of the same untouched website. Bigger than many real fixes are worth, which makes one score hard to trust.

The same website, twice, nothing changed in between

measured, not an example
run one
60
run two
51
9 points apart

Same website. Ran it twice. Changed nothing. Still nine points apart. One score on its own is not enough.

Only five things add to the score.

Extra script, blocked images, big files. All useful to clean up. On their own they add zero to the score. They only help if fixing one speeds up one of the five that count, and most reports never draw that line.

Every square is one item in a speed report. The amber ones are the only ones that add marks.

5 scored  ·  44 not

And a slow site gains almost nothing for getting a bit faster.

The scale bends. Going from 7.3 seconds to 6 seconds feels better for visitors, and it is worth about two points. You can work all afternoon and watch the score barely move.

Marks out of 25 for how long the biggest thing takes to show.

2.5s 4.0s 5.0s 6.0s 7.3s 22.5 1.3

22.5 marks at 2.5s  ·  1.3 marks at 7.3s

What you get

Four steps.

The free check on this page does the first three. Lab proof and ready files are available with credits when a finding supports them.

01

Find it

What is slow, and which file is causing it.

02

Order it

What to change first, and how many points it might earn.

03

Check it

Check again after you change something. Did the score really move?

04

Say so

It worked, it did not, or we cannot tell yet. The numbers sit behind that call.

Ways to use it

Use it your way.

Same engine. Website for everyone. Terminal and Cursor for developers. API when you wire your own tools.

01

Website

Paste a site. Free report. Sign in to check a fix, find the file, or get a smaller image.

pafcore.site
Check a site
02

Terminal

Full report from our servers. Sign in, scan, then see if a suggested change would help.

pafcore login
pafcore scan https://yoursite.com
pafcore test 1
CLI docs
03

Cursor or Claude

MCP tools so an agent can scan, check a fix, and find the file.

pafcore mcp install
MCP docs
04

API

Same routes the site and CLI use. Session header. Curl ready.

POST /v1/scans
GET  /v1/findings/:id/:n
API docs

Need score and noise only on your own machine, with no file names? That is a different free tool: npx @pafcore/cli scan. See measure only CLI.

The tools that already exist

All three are good. None of them close this gap.

Not a pitch against them. I use all three. Here is what each does well, and what it still leaves you with.

Lighthouse

Opens your website in a real browser and gives it a score. It has got better, and it can name files. It will tell you which image is too big.

What it leaves you It grades one run. Run it again and the number changes, and it will not say whether that change means anything.

PageSpeed Insights

Lighthouse on Google machines, plus real visitor data from Chrome. The visitor half is the part worth having, because search cares about it.

What it leaves you That half takes weeks to show a change you ship. Neither half tells you if this morning's fix beat the score moving by itself.

AI coding tools

Good at writing the fix. Point one at a report and it can shrink an image or split a big script. Faster than doing it by hand.

What it leaves you It reads the same report, so it picks the biggest number rather than the one you can win, and it checks its work by running once.

Questions

The usual questions.

Is this just Lighthouse with a nicer look?

It uses Lighthouse for the lab numbers, so the raw scores match. Two things are different. Lighthouse grades one run and stops. PafCore loads the page three times and shows how far the score moves on its own, so you can tell a real gain from a lucky run. It also finds the file behind the slow part, then orders fixes by how many points they might earn.

If you only need a grade, Lighthouse is free and already on your computer. Use it.

Can I paste the report into Cursor and let it fix things?

For the fix itself, often yes, and faster than you would. The hard part is choosing what to fix. The tool reads the same report you do, so it picks whatever number looks worst, not whatever you can win, and it checks its work by running the test once more.

One more run cannot tell a real gain from the score moving by itself. Measuring that move is where this starts.

What will it cost?

The full report on this page is free for public websites. Three free reports a day. After that, another report costs 1 credit when you are signed in. Fair use still stops one site soaking the scanner.

Sign in does not add credits. Buy a pack for the next steps: see if a suggested change would help, find the file, download a smaller image, or get code to paste. A pack is $5 for 20 credits. Credits also buy another full report after your free daily limit. Pro Watch ($19/mo) is separate: schedules, history, alerts, and 60 credits each month.

When can I use it?

Now, at the top of this page. Paste a website address and you get the real report: the score, how far it moves on its own, the file behind the slowest thing, and what to fix first.

Same engine also runs from the terminal, Cursor or Claude (MCP), and the HTTP API. See Ways to use it and the docs.

There is a separate free command for score and movement only on your machine. It does not name the slow file the way this page does. Details: measure only CLI.

Can I use it from Cursor or the terminal?

Yes. The website is the easy path. Developers can use the engine CLI, connect MCP in Cursor or Claude, or call the same HTTP API.

Start here: CLI, MCP, API.

Does it work on any site?

Anything a browser can open without signing in, to start with. Sites behind a login, and anything slow only after a click, are harder and come later.

It will not work on everything. When it cannot measure something, it says so rather than guessing.

Who builds it?

A small product, shipped in the open. Decisions and progress are posted on X. Security and product mail: hello@pafcore.site.

' } el('rep-share').addEventListener('click', function () { var note = el('rep-act-msg') var href = reportShareHref() if (!scanId) { note.textContent = 'No report link yet.' return } var done = function () { note.textContent = 'Link copied. Paste it anywhere.' setTimeout(function () { note.textContent = '' }, 2500) } if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(href).then(done).catch(function () { note.textContent = 'Could not copy. Use the link box above.' }) } else { note.textContent = 'Could not copy. Use the link box above.' } }) el('rep-copy').addEventListener('click', function () { var note = el('rep-act-msg') if (!lastText) { note.textContent = 'Nothing to copy yet.'; return } navigator.clipboard.writeText(lastText).then(function () { note.textContent = 'Copied the text report.' setTimeout(function () { note.textContent = '' }, 2500) }).catch(function () { note.textContent = 'Could not copy. Open the full report and select it.' }) }) el('rep-dl').addEventListener('click', function () { var note = el('rep-act-msg') if (!lastReport && !lastText) { note.textContent = 'Nothing to download yet.' return } var host = 'page' try { host = new URL((lastReport && lastReport.url) || scannedUrl || '').hostname.replace(/^www\./, '') } catch (e) {} var html = buildDownloadHtml(lastReport || { text: lastText, url: scannedUrl }) var a = document.createElement('a') var blob = new Blob([html], { type: 'text/html;charset=utf-8' }) a.href = URL.createObjectURL(blob) a.download = 'pafcore-' + host + '.html' a.click() URL.revokeObjectURL(a.href) note.textContent = 'Downloaded a styled report.' setTimeout(function () { note.textContent = '' }, 2500) }) var linkCopy = document.getElementById('try-link-copy') if (linkCopy) { linkCopy.addEventListener('click', function () { var field = document.getElementById('try-link') var why = document.getElementById('try-keep-why') if (!field) return var done = function () { linkCopy.textContent = 'Copied' if (why) why.textContent = 'Paste it somewhere you will find it again.' setTimeout(function () { linkCopy.textContent = 'Copy' }, 2000) } /* Clipboard access is refused on some setups, and select-plus-copy still works there. Falling back beats a button that quietly does nothing. */ if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(field.value).then(done, function () { field.select(); done() }) } else { field.select() try { document.execCommand('copy') } catch (e) {} done() } }) } /* Coming back to a scan. Either a link somebody was sent, or this browser remembering what it started. The link wins: it was chosen on purpose. */ var fromLink = idFromUrl() var saved = fromLink ? { id: fromLink, url: '', at: Date.now() } : recall() if (saved) { scanId = saved.id scannedUrl = saved.url startedAt = saved.at show(document.getElementById('results'), true) show(state, true) status.textContent = fromLink ? 'Fetching that report' : 'Picking up the scan you started' step(3) btn.disabled = true; btn.textContent = 'Checking' input.value = saved.url || '' showLink(saved.id) showWaitMail({}) bringIntoView(document.getElementById('results')) timer = setTimeout(poll, 800) } })()