2 of 6 key pages fail Core Web Vitals on mobile
/templates/invoice LCP rose from 2.6 s to 3.4 s; the hero image is the LCP element and is not preloaded. CLS on the net 30 post is 0.19 from a late ad slot.
Every Monday: LCP, INP and CLS at the 75th percentile for your key pages on mobile, pass or fail, and what moved since last week.
Reads
You get
The card on the right is a sample. Yours shows your own numbers and updates in place every run.
What lands on your board
/templates/invoice LCP rose from 2.6 s to 3.4 s; the hero image is the LCP element and is not preloaded. CLS on the net 30 post is 0.19 from a late ad slot.
Search Console groups Core Web Vitals by URL pattern and updates slowly, and PageSpeed Insights answers one URL at a time. Neither tells you on Monday that the pricing page got slower last week. Lab scores from Lighthouse are noisy and are not what Google uses for page experience.
This skill reads the field data, the 75th percentile of real Chrome users, for the pages you care about: LCP, INP and CLS on mobile, each pass or fail, against the week before. For a page that fails, it runs a PageSpeed Insights test to name the likely culprit, such as the LCP element or the shifting banner.
Keep 5 to 20 URLs that matter, such as home, pricing, top landing pages and a sign-up page, plus the origin (https://example.com) as a site-wide line.
For each URL, POST https://chromeuxreport.googleapis.com/v1/records:queryHistoryRecord?key=<key> with url, formFactor: "PHONE", metrics: ["largest_contentful_paint", "interaction_to_next_paint", "cumulative_layout_shift"] and collectionPeriodCount: 2. The last value of each percentilesTimeseries.p75s is this week; the one before is last week.
A URL without enough Chrome traffic returns 404. Use the origin record for it, and label the row "origin data" so nobody mistakes it for the page's own numbers.
Good means LCP at or under 2,500 ms, INP at or under 200 ms and CLS at or under 0.1, all at p75. A page passes when all three are good. Flag any metric that worsened by 10% or more on last week, even while passing.
For each failing page, call GET https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=<url>&strategy=mobile&category=performance&key=<key> and read the Lighthouse diagnostics in lighthouseResult.audits for the LCP element, long tasks or layout shifts. Lab data explains; field data decides.
With BRIEFKIN_TOKEN set, the agent sends the result as one card that updates in place every run. Without it, you get the report in the chat.
Pick your agent, where the data comes from and how to schedule it; the commands below follow.
One command. It puts the SKILL.md in ~/.claude/skills and in ~/.agents/skills, which Codex, Cursor, Gemini CLI, Copilot CLI and OpenCode read too.
shellcurl -fsSL https://briefkin.dev/skills/pagespeed-insights-core-web-vitals-report/install | shAsk Claude Code:
promptRun the pagespeed-insights-core-web-vitals-report skillOr paste the prompt instead of installing:
promptFor each URL in my list, read Chrome UX Report field data with the CrUX History API (records:queryHistoryRecord, formFactor PHONE, metrics largest_contentful_paint, interaction_to_next_paint and cumulative_layout_shift, collectionPeriodCount 2). Use the last p75 value as this week and the one before as last week; if a URL has no data, use the origin and label it. A page passes when LCP is at most 2,500 ms, INP at most 200 ms and CLS at most 0.1. Show a table of pages with the three values and pass or fail, list passing pages that got 10% worse, and for failing pages run the PageSpeed Insights API on mobile and tell me the likely cause from the Lighthouse diagnostics.Mondays at 9:00, from cron on any machine where Claude Code is signed in:
crontab0 9 * * 1 claude -p "Run the pagespeed-insights-core-web-vitals-report skill"Add it with crontab -e. A laptop asleep at that time runs it when it wakes if you use launchd or Task Scheduler instead; GitHub Actions works for the API route.
Connect Briefkin once with curl -fsSL https://briefkin.dev/install | sh and every run lands on your board as a report card. How setup works
SKILL.md---
name: pagespeed-insights-core-web-vitals-report
description: "Every Monday: LCP, INP and CLS at the 75th percentile for your key pages on mobile, pass or fail, and what moved since last week. Use when the user asks for this, or when it runs on a schedule."
---
# PageSpeed Insights Core Web Vitals report
Every Monday: LCP, INP and CLS at the 75th percentile for your key pages on mobile, pass or fail, and what moved since last week.
Search Console groups Core Web Vitals by URL pattern and updates slowly, and PageSpeed Insights answers one URL at a time. Neither tells you on Monday that the pricing page got slower last week. Lab scores from Lighthouse are noisy and are not what Google uses for page experience.
This skill reads the field data, the 75th percentile of real Chrome users, for the pages you care about: LCP, INP and CLS on mobile, each pass or fail, against the week before. For a page that fails, it runs a PageSpeed Insights test to name the likely culprit, such as the LCP element or the shifting banner.
## Two ways to get the data
Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.
## Route A: API or MCP server
### What you need
- A Google Cloud API key with the PageSpeed Insights API and the Chrome UX Report API enabled, in `PAGESPEED_API_KEY`. Both are free; CrUX allows 150 queries a minute.
If something is missing, say what and stop; do not invent numbers.
### Steps
1. **List the pages**: Keep 5 to 20 URLs that matter, such as home, pricing, top landing pages and a sign-up page, plus the origin (`https://example.com`) as a site-wide line.
2. **Read the field data** (PageSpeed Insights): For each URL, `POST https://chromeuxreport.googleapis.com/v1/records:queryHistoryRecord?key=<key>` with `url`, `formFactor: "PHONE"`, `metrics: ["largest_contentful_paint", "interaction_to_next_paint", "cumulative_layout_shift"]` and `collectionPeriodCount: 2`. The last value of each `percentilesTimeseries.p75s` is this week; the one before is last week.
3. **Fall back to the origin** (PageSpeed Insights): A URL without enough Chrome traffic returns 404. Use the origin record for it, and label the row "origin data" so nobody mistakes it for the page's own numbers.
4. **Judge pass or fail**: Good means LCP at or under 2,500 ms, INP at or under 200 ms and CLS at or under 0.1, all at p75. A page passes when all three are good. Flag any metric that worsened by 10% or more on last week, even while passing.
5. **Diagnose failing pages** (PageSpeed Insights): For each failing page, call `GET https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=<url>&strategy=mobile&category=performance&key=<key>` and read the Lighthouse diagnostics in `lighthouseResult.audits` for the LCP element, long tasks or layout shifts. Lab data explains; field data decides.
## Route B: the browser
### What you need
- No account is needed; pagespeed.web.dev is public. A Google sign-in only matters if you also open the Core Web Vitals report in Search Console for URL groups.
If something is missing, say what and stop; do not invent numbers.
### Steps
Start at https://pagespeed.web.dev/. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.
1. **Test each page**: Paste the first URL from your list and click **Analyze**. On the **Mobile** tab, the top section (what real users are experiencing) shows the Core Web Vitals assessment, Passed or Failed, with LCP, INP and CLS at the 75th percentile over the last 28 days.
2. **Note pages without their own data**: When a page has too little Chrome traffic, the section switches to origin data; the toggle above it says **This URL** or **Origin**. Use the origin numbers and label that row "origin data".
3. **Compare with last week**: PageSpeed Insights shows only the current 28-day window, so compare with the values you kept from last week's run (keep this week's too). A page passes when LCP is at most 2,500 ms, INP at most 200 ms and CLS at most 0.1; flag any metric that worsened by 10% or more even while passing.
4. **Diagnose failing pages**: Scroll to the Lighthouse section below for a failing page and read the audits that name the cause: the Largest Contentful Paint element, long main-thread tasks, and layout shift culprits. Lab data explains; the field data above decides.
5. **Add the origin line**: Run the bare origin (`https://example.com`) once as a site-wide row, then write the table: page, LCP, INP, CLS, pass or fail, change on last week, the watch list and the likely causes.
Note: The page shows one 28-day window with no history, so a week-on-week comparison depends on keeping last week's values. Each analysis takes about a minute; for more than 20 URLs the API route is faster. Field values are the same CrUX data the API returns, updated daily here against weekly in the History API, so small differences are normal.
## The report
- **Per page**: LCP, INP and CLS at p75 on mobile, pass or fail, and the change on last week.
- **Origin line** for the whole site.
- **Failing pages** with the likely cause from a Lighthouse run.
- **Watch list**: passing pages that got 10% worse.
## Post it to Briefkin
When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.
```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
-H "authorization: Bearer $BRIEFKIN_TOKEN" \
-H "content-type: application/json" \
-d @- <<'JSON'
{
"v": 1,
"event_id": "pagespeed-insights-core-web-vitals-report/<date of this run, e.g. 2026-10-16>",
"item_key": "pagespeed-insights-core-web-vitals-report",
"project": "example.com",
"source": "PageSpeed Insights Core Web Vitals report skill",
"kind": "update",
"title": "2 of 6 key pages fail Core Web Vitals on mobile",
"summary": "/templates/invoice LCP rose from 2.6 s to **3.4 s**; the hero image is the LCP element and is not preloaded. CLS on the net 30 post is **0.19** from a late ad slot.",
"widget": [
{
"type": "Table",
"props": {
"columns": [
"Page",
"LCP",
"INP",
"CLS",
"Result"
],
"align": [
"left",
"right",
"right",
"right",
"left"
],
"rows": [
[
"/",
"2.1 s",
"140 ms",
"0.04",
"Pass"
],
[
"/pricing",
"2.4 s",
"180 ms",
"0.02",
"Pass"
],
[
"/templates/invoice",
"3.4 s",
"170 ms",
"0.08",
"Fail: LCP"
],
[
"/blog/net-30-payment-terms",
"2.2 s",
"120 ms",
"0.19",
"Fail: CLS"
],
[
"/signup",
"1.9 s",
"160 ms",
"0.01",
"Pass"
],
[
"/features (origin data)",
"2.3 s",
"150 ms",
"0.05",
"Pass"
]
]
}
},
{
"type": "Callout",
"props": {
"text": "/pricing INP went from 150 ms to 180 ms. Still passing, but on the watch list.",
"tone": "info"
}
}
]
}
JSON
```
Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.
## Run it on a schedule
Suggested: Mondays at 9:00 (`0 9 * * 1`). From cron, with the agent signed in on that machine:
```bash
0 9 * * 1 claude -p "Run the pagespeed-insights-core-web-vitals-report skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```
Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/pagespeed-insights-core-web-vitals-report#schedule
Source: https://briefkin.dev/skills/pagespeed-insights-core-web-vitals-report
A Google Cloud API key with the PageSpeed Insights API and the Chrome UX Report API enabled, in PAGESPEED_API_KEY. Both are free; CrUX allows 150 queries a minute.
claude mcp add --transport stdio chrome-devtools -- npx -y chrome-devtools-mcp@latest (source). Codex and Cursor run the same command.PAGESPEED_API_KEY. Enable the Chrome UX Report API on the same key if the skill also reads CrUX history.npx lighthouse https://example.com --only-categories=performance --output=json --quiet --chrome-flags="--headless" runs the lab test on your own machine or in CI.All of this reads public performance data. Restrict the API key to the PageSpeed Insights and Chrome UX Report APIs so a leaked key is useless for anything else.
Lighthouse runs one simulated load on a test device; CrUX reports what real Chrome users experienced over 28 days. Google's page experience signals use the field data, so the report judges pass and fail on CrUX and uses Lighthouse only to point at causes.
Each CrUX value is a rolling 28-day window, updated weekly in the History API. A fix shipped today moves the p75 a little each week and shows in full after about four. Watch the direction of the weekly values rather than expecting a jump.
No. The skill runs with your own agent and gives you the report in the chat. With a Briefkin token set, each run also posts it to your board as a report card, so you can glance at it instead of asking again.
Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Windsurf and Amp all read SKILL.md files. The install command puts it in ~/.claude/skills and ~/.agents/skills, where they look. ChatGPT, the Claude app and Grok take the prompt instead. Pick your agent under "Install and run it" and the commands change to match.
Yes. Switch the data source to "Your browser" and the steps change to the PageSpeed Insights pages themselves: the agent opens pagespeed.web.dev in a browser you are signed in to and reads the numbers off the page. Claude Code, Codex, Cursor, Claude app and ChatGPT can drive a browser out of the box; Gemini CLI, Copilot CLI and OpenCode need a Playwright or Chrome DevTools MCP server first. It is slower than the API and needs you signed in, so it suits a report you run by hand or from a scheduler on your own computer.
Skills are free to use with any agent. Briefkin is where their results land: one board for every report, number and question your agents send, with a ping when something needs you.
Free during the open beta. No card.