--- name: pagespeed-95-gate description: Use this skill whenever a user asks for PageSpeed Insights, Lighthouse, Core Web Vitals, 95+ scores, performance gates, DataForSEO Lighthouse checks, or production page-speed monitoring. It runs mobile and desktop audits and blocks release until Performance, Accessibility, Best Practices, and SEO are all 95+ or documented as unavailable. metadata: author: Clvrwrk version: "1.0" references: pagespeed_insights_api: https://developers.google.com/speed/docs/insights/v5/get-started --- # PageSpeed 95 Gate This skill validates production-like pages with PageSpeed Insights and DataForSEO Lighthouse. It treats scores as a release gate, but it also records when a result is unavailable because an API key, network path, or deployed URL is missing. It is also a repair workflow. If the user asks to improve, fix, validate, or "get scores where they need to be," do not stop after running an audit. Read the failing diagnostics, patch the shared root causes, rebuild, redeploy or push when requested, and rerun PageSpeed before claiming success. ## Inputs - Read `seo-maintenance.config.json` when present. - Use configured `criticalPages` first, then all indexable routes when the user asks for full coverage. - Use `PAGESPEED_API_KEY` when available. - Use DataForSEO Lighthouse when the MCP/tool is available. ## Workflow 1. Confirm the audited URL set: - Critical pages for quick gate. - Full route inventory for complete maintenance run. - If the repo has `scripts/pagespeed-95-gate.mjs`, prefer that runner; it reads `PAGESPEED_API_KEY`, audits `criticalPages` from `seo-maintenance.config.json`, and writes `reports/seo-maintenance/pagespeed-latest.json`. 2. Confirm the environment: - Prefer production URLs for PageSpeed and external Lighthouse. - Use local preview only for preflight diagnostics, not final production scores. 3. Run PageSpeed Insights for each URL: - Strategy: `mobile` and `desktop`. - Categories: performance, accessibility, best-practices, seo. - Save scores, key audits, Core Web Vitals field data when available, and API errors. 4. Run DataForSEO Lighthouse for each URL: - Enable JavaScript rendering. - Save category scores and top opportunities/diagnostics. 5. Gate each page: - Pass only when all four categories are >= 0.95 for both mobile and desktop. - Warn when lab scores pass but field data is poor or unavailable. - Fail when any required score is below 0.95. 6. When scores fail, move into the repair loop below before reporting final success. ## Repair Loop 1. Read `reports/seo-maintenance/pagespeed-latest.json` and group failures by recurring diagnostics across URLs. Prefer shared template fixes over page-by-page tweaks. 2. Inspect the source for each shared template before patching: layout, header/footer, service detail, location detail, project index, contact page, and analytics/script loading. 3. Fix in this priority order: - Accessibility category blockers below 95: missing `
`, contrast, visible text labels that do not match accessible names, heading order, and focusable descendants inside `aria-hidden`. - TBT/INP/long-task blockers: third-party scripts, large synchronous bundles, forced reflow, global animation libraries, and `client:load` hydration. - LCP blockers: image discovery, preload/fetch priority, TTFB, element render delay, and oversized hero assets. - Image delivery: exact aspect ratio crops, `srcset`, `sizes`, WebP/AVIF, and explicit `width`/`height`. - Network and deployment: compression, CDN/proxy, cache headers, and server response time. 4. Rebuild locally after edits. If the user wants Coolify to pick it up, commit and push only after build passes. 5. Rerun the PageSpeed gate against production after deployment. If Coolify has not yet deployed the pushed commit, say that clearly and rerun after it does. ## High-Impact Fix Patterns ### LCP - Ensure the LCP image is present in raw server-rendered HTML, not inserted by client JavaScript. - Add both a preload and image-level priority for the LCP image: - `` - `` - Use accurate `imagesizes`/`sizes`. Avoid lazy `100vw` when the image is constrained by a max-width container. - Check the LCP breakdown in PSI. Diagnose by subpart: - high TTFB: server/CDN/cache issue - high resource load delay: image not discoverable or not preloaded - high resource load duration: image too large or wrong format - high element render delay: render-blocking CSS/JS or font delay ### TBT, INP, and Forced Reflow - Treat TBT as a first-class blocker. It has heavy Lighthouse scoring weight and usually explains broad desktop/mobile failures. - Defer or delay analytics and tracking scripts when possible. Keep attribution requirements intact, but avoid running non-critical third-party code before first paint. - Remove or scope global animation libraries on pages where static CSS or IntersectionObserver is enough. Watch for large chunks such as `ScrollTrigger`. - Avoid read-after-write layout code. Cache geometry (`scrollHeight`, `getBoundingClientRect`, `offsetWidth`, etc.) before style writes. - Animate only `transform` and `opacity`; avoid animating `height`, `width`, `top`, `left`, margin, padding, or font size. - Use CSS containment for marquees/carousels and other continuously animated regions: `contain: layout style` where safe. ### Image Delivery - Generate image variants that match the displayed aspect ratio before CSS cropping. Do not rely on `object-fit: cover` to hide oversized sources. - Include a `720w` step for card images when mobile Lighthouse chooses roughly 412px x 1.75 DPR. - Every image must have intrinsic `width` and `height` attributes. - Prefer WebP or AVIF for photographic assets. Keep PNG for logos only when transparency or source fidelity requires it. - For large index pages, calculate total transferred image bytes and remove hidden/preloaded/unused images from the initial viewport. ### Accessibility Gates - Every document must expose exactly one useful `
` landmark around page-specific content. - Visible button/link text should appear in the accessible name unless there is a good reason. - Keep heading order sequential within reusable cards and page sections. - Do not place focusable descendants inside `aria-hidden="true"` containers. - Fix contrast at the token/component level so repeated cards and forms all improve together. ### Coolify and Production Delivery - Verify production commit parity before interpreting PSI results. PageSpeed audits the deployed site, not the local build. - Confirm compression and cache headers for static assets. - Use Cloudflare/CDN caching for static Astro assets when available. - If production still serves an older commit, mark the PageSpeed result as "deployment pending" rather than a code failure. ## Verification Discipline - A PageSpeed run that writes a report is not a success. Success means every audited page passes the configured gate. - PageSpeed can fluctuate. For final release verification, prefer three runs and use the median score per page/strategy when time and API quota allow. Set `PAGESPEED_RUNS=3` for the local runner. - Include the score delta from the previous report when available. - If the gate fails, the final response must say "FAIL" plainly and list the next highest-leverage fixes. - Do not commit updated report files unless the user asks for reports to be versioned or the run is part of a maintenance-report commit. ## Report Fields For every audited URL report: - `psi.mobile.performance` - `psi.mobile.accessibility` - `psi.mobile.bestPractices` - `psi.mobile.seo` - `psi.desktop.performance` - `psi.desktop.accessibility` - `psi.desktop.bestPractices` - `psi.desktop.seo` - `dataForSeo.mobile` - `dataForSeo.desktop` - `pass95` - `topFixes` ## Pass/Fail Rules - **Pass:** all four categories are 95+ on mobile and desktop in both PageSpeed and DataForSEO when both are available. - **Warn:** one provider is unavailable, field data is missing, or production differs from local build. - **Fail:** any available required category is below 95.