pagespeed-optimizer — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited pagespeed-optimizer (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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.
Fix in phases. Verify between phases. Never skip verification.
The three phases are:
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.
one, ask them to run https://pagespeed.web.dev against their mobile origin and paste the result.
scripts/parse-pagespeed.mjs to extract the baseline metrics. Recordthem — you'll compare against these after each phase.
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.
HTML, Astro, etc.). Your concrete suggestions will depend on this.
Read references/phase-1-images.md before doing any image work.
Minimum rules for this phase:
loading="eager" andfetchpriority="high". Everything else gets loading="lazy" and decoding="async".
<img> and <source> must have explicit width and heightattributes — this prevents CLS.
scripts/optimize-images.mjs handles resizing and conversion.
a 4000px image to display at 400px.
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.
Read references/phase-2-fonts.md before doing any font work.
Minimum rules for this phase:
render-blocking requests. Remove any @import that hits fonts.googleapis.com.
caption over the LCP image). That font, and only that font, gets fully self-hosted.
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).
non-render-blocking via: <link rel="stylesheet" href="..." media="print" onload="this.media='all'" />
scripts/extract-font-weights.mjs to find which font weights yourcodebase 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.
Read references/phase-3-javascript.md before doing any JS work.
Minimum rules for this phase:
React.lazy() / dynamic import().
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).
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.
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.
Read references/regression-triage.md for full treatment. Shortlist:
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.
critical path. Preload the 1–2 weights the LCP text actually uses.
loading="lazy" on the hero image isan anti-pattern — the browser defers the image everyone is waiting for.
Quality 70–75 is usually the sweet spot for WebP.
single largest source of unused JavaScript. Defer it.
Use scripts/parse-pagespeed.mjs to normalise reports into a consistent shape regardless of input type. The script accepts:
It outputs the five key metrics (score, LCP, TBT, CLS, FCP), the top-3 highest-saving opportunities, and a recommended phase to start with.
unless you have dev-mode access). The skill relies on being able to edit HTML/CSS/JS.
config, database tuning, hosting tier — and outside this skill's scope.
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.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.