agentsclimarketplace

Pagespeed optimizer

Skill qzachh/skills/pagespeed-optimizer

Use when the user mentions PageSpeed Insights, Core Web Vitals, LCP, TBT, CLS, site speed, page speed score, slow website, performance optimisation, or similar. Guides a phased, verification-gated approach — images first, fonts second, JavaScript third — specifically designed to avoid the regressions that typically occur when AI agents try to fix everything in one pass. Encodes lessons from a real 27→80 optimisation journey where an "everything at once" approach caused a 77→62 regression that took two more iterations to recover from.From its SKILL.md

Install
npx -y skills add qzachh/skills --skill pagespeed-optimizer

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

7.3 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it

PageSpeed Optimizer

You are helping the user improve their PageSpeed Insights score. This skill exists because PageSpeed optimisation is deceptively easy to break: fixing one metric often worsens another, and fixing "everything at once" causes regressions that are hard to unpick.

Prime Directive

Fix in phases. Verify between phases. Never skip verification.

The three phases are:

  1. Images — usually the biggest single win (often 80–99% of savings)
  2. Fonts — biggest render-blocking reduction
  3. JavaScript — smallest improvement per hour of work, but necessary for TBT

If you are tempted to do more than one phase in a single pass, STOP. The reference document this skill is built on records a real regression where inlining "an LCP skeleton" alongside font changes dropped the score from 77 to 62, which then took two more iterations to recover from.

Before You Start

  1. Read the user's PageSpeed report (JSON, text, or PDF). If they haven't run one, ask them to run https://pagespeed.web.dev against their mobile origin and paste the result.
  2. Use scripts/parse-pagespeed.mjs to extract the baseline metrics. Record them — you'll compare against these after each phase.
  3. Identify the LCP element. This is usually reported in the "Largest Contentful Paint element" audit. It's almost always either (a) a specific hero image or (b) a specific text element. The LCP element gets different treatment than everything else.
  4. Ask the user what framework/bundler they use (Vite, Next.js, Nuxt, plain HTML, Astro, etc.). Your concrete suggestions will depend on this.

Phase 1: Images

Read references/phase-1-images.md before doing any image work.

Minimum rules for this phase:

  • The LCP image (if the LCP element is an image) gets loading="eager" and fetchpriority="high". Everything else gets loading="lazy" and decoding="async".
  • Every <img> and <source> must have explicit width and height attributes — this prevents CLS.
  • All raster images that can be WebP should be WebP. The optimise script at scripts/optimize-images.mjs handles resizing and conversion.
  • Image target widths are 2× the CSS display width (retina). Don't ship a 4000px image to display at 400px.
  • Use the pagespeed-optimizer.config.mjs template (see phase-1 reference) to declare image source → target-width mappings.

After this phase: run PageSpeed again. LCP should drop substantially. If it didn't, re-read the report — you probably didn't target the LCP image correctly.

Phase 2: Fonts

Read references/phase-2-fonts.md before doing any font work.

Minimum rules for this phase:

  • Never use CSS @import url(...) for fonts. It serialises into render-blocking requests. Remove any @import that hits fonts.googleapis.com.
  • Identify the LCP font (the one used by the LCP text element, or by the caption over the LCP image). That font, and only that font, gets fully self-hosted.
  • For the LCP font: download woff2 files for each weight actually used. Put them in public/fonts/<family>/. Add <link rel="preload" as="font" type="font/woff2" crossorigin> for the one or two most-critical weights. Inline the @font-face declarations in a <style> block inside <head> (not in an external CSS file).
  • Secondary fonts can stay on Google Fonts CDN if loaded non-render-blocking via: <link rel="stylesheet" href="..." media="print" onload="this.media='all'" />
  • Run scripts/extract-font-weights.mjs to find which font weights your codebase actually uses. Do not preload weights nothing renders with.

After this phase: run PageSpeed again. Render-blocking time should be dramatically reduced. If TBT or LCP regressed, STOP and read references/regression-triage.md.

Phase 3: JavaScript

Read references/phase-3-javascript.md before doing any JS work.

Minimum rules for this phase:

  • Route-level code splitting. Every route gets its own chunk via React.lazy() / dynamic import().
  • Vendor chunking. Heavy dependencies get their own chunk so they can be cached across routes. For Vite, use build.rollupOptions.output.manualChunks with a vendor-react group and a vendor-ui group (whatever UI library kit dominates your bundle).
  • Third-party scripts deferred. Google Tag Manager, analytics, chat widgets — these load after window.onload + 2 second delay, not synchronously in the head. They are NOT your responsibility to make fast; they are your responsibility to defer.
  • Do not touch the LCP image/font setup when optimising JS. Cross-phase changes are exactly what caused the 77→62 regression.

After this phase: run PageSpeed again. TBT should drop; Main Thread Work should drop. LCP and CLS should be unchanged — if they regressed, references/regression-triage.md.

Common Traps

Read references/regression-triage.md for full treatment. Shortlist:

  • LCP skeletons that hurt LCP. Adding a "skeleton" placeholder intended to paint before React hydrates can actually make LCP worse because PageSpeed measures the real element, and the skeleton counts as layout shift or render-delay. Measure; don't assume.
  • Preloading too many fonts. Preloading 5 font weights saturates the critical path. Preload the 1–2 weights the LCP text actually uses.
  • Lazy-loading the LCP image. loading="lazy" on the hero image is an anti-pattern — the browser defers the image everyone is waiting for.
  • Using @import anywhere in the critical CSS path.
  • Compressing images below ~65 quality. Looks bad; savings plateau. Quality 70–75 is usually the sweet spot for WebP.
  • Fetching third-party analytics synchronously. It will always be the single largest source of unused JavaScript. Defer it.

Parsing PageSpeed Reports

Use scripts/parse-pagespeed.mjs to normalise reports into a consistent shape regardless of input type. The script accepts:

  • A path to a JSON file (from the PageSpeed Insights API)
  • A path to a plain text file (report copy-pasted from a PDF)
  • Raw text via stdin

It outputs the five key metrics (score, LCP, TBT, CLS, FCP), the top-3 highest-saving opportunities, and a recommended phase to start with.

What This Skill Does NOT Cover

  • Sites you can't edit source for (Wix, Squarespace, Shopify themes — unless you have dev-mode access). The skill relies on being able to edit HTML/CSS/JS.
  • Server response time (TTFB) issues. These are server-side — CDN config, database tuning, hosting tier — and outside this skill's scope.
  • Scores above ~90. The last 10 points are usually diminishing returns: subresource integrity, brotli compression tuning, HTTP/3, etc. If the user is at 85+ and wants 95+, tell them the remaining work is infrastructure-level, not application-level.

What ships with it: 10 files

55.9 KB alongside SKILL.md, 4 of them executable

Gives 0 of the 12 instructions most performance cost skills give in ~1.7k tokens

Counted across 803 of the 1,058 authors here whose files we hold, read 2026-08-07

  • Keep skill files under 500 lines or tokensin 82 of 803, across 16 files
  • Use imperative form in instructionsin 80 of 803, across 9 files
  • Draft assertions while test runs are in progressin 75 of 803, across 9 files
  • Create two to three realistic test promptsin 74 of 803, across 9 files
  • Write skill descriptions to be pushyin 72 of 803, across 7 files
  • Save test cases to evals JSONin 72 of 803, across 6 files
  • Ask questions about edge cases and input formatsin 72 of 803, across 7 files
  • Save timing data immediately when runs completein 70 of 803, across 5 files
  • Include all trigger conditions in the skill descriptionin 69 of 803, across 3 files
  • Launch all test runs in a single turn or simultaneouslyin 69 of 803, across 3 files
  • Capture intent before writing a skillin 67 of 803, across 1 file
  • Import directly instead of barrel filesin 52 of 803, across 15 files

Said here and by no other author read

  • fix issues in sequential phases
  • verify metrics between phases
  • target images first then fonts then JavaScript
  • identify the largest contentful paint element
  • self-host and preload only the LCP font
  • inline critical font face declarations in head

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 326,852. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.