Skip to content
cccskills
FreePublished on GitHub

performance-and-web-vitals

Lighthouse audits and Core Web Vitals — LCP, CLS, INP. Use when optimising page load, layout shift, input delay, images, fonts or render-blocking resources.

The English summary is being prepared. Showing the original description.

Run score Not tested

See how to install

Files included (1)

  • SKILL.md7.8 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Performance and Web Vitals

Run a Lighthouse Audit

# CLI audit — outputs JSON and HTML report
npx lighthouse https://example.com --output html --output-path ./lighthouse-report.html

# Headless, useful in CI
npx lighthouse https://example.com --chrome-flags="--headless" --output json --output-path ./report.json

# Audit specific categories only
npx lighthouse https://example.com --only-categories=performance,accessibility,seo

Or open Chrome DevTools → Lighthouse tab → Analyse page load.

Target scores:

CategoryTarget
Performance≥ 90
Accessibility100
Best Practices≥ 95
SEO≥ 95

Core Web Vitals

LCP — Largest Contentful Paint

How fast does the main content appear?

Target: ≤ 2.5s

LCP measures when the largest visible element (hero image, heading, video poster) renders. It is the user's perception of "did the page load?"

Common causes and fixes:

CauseFix
Unoptimised hero imageUse WebP/AVIF, correct size, fetchpriority="high"
Image not preloaded<link rel="preload" as="image" href="hero.webp">
Render-blocking CSS/JSDefer non-critical JS, inline critical CSS
Slow server responseCDN, caching headers, edge delivery
Web font blocking renderfont-display: swap or optional
<!-- Preload LCP image -->
<link rel="preload" as="image" href="hero.webp" fetchpriority="high">

<!-- LCP image: no lazy loading -->
<img src="hero.webp" alt="..." fetchpriority="high" width="1200" height="600">

Never use loading="lazy" on the LCP image — it delays the most important render.


CLS — Cumulative Layout Shift

Does content jump around while loading?

Target: ≤ 0.1

CLS measures unexpected layout shifts — content moving after it has rendered. Caused by images without dimensions, late-loading ads, fonts swapping, or dynamic content injected above existing content.

Common causes and fixes:

CauseFix
Images without width/heightAlways set width and height on <img>
Web font swapUse font-display: optional or preload fonts
Dynamic content above foldReserve space with min-height on containers
Late-loading ads or embedsReserve fixed dimensions for ad slots
Animations that shift layoutAnimate transform only, never top/left/width/height
<!-- Always include dimensions -->
<img src="product.jpg" width="400" height="300" alt="...">
/* Reserve space for dynamic content */
.ad-slot { min-height: 250px; }

/* Animate transform, not layout properties */
.slide-in { transform: translateY(0); transition: transform 300ms; }

INP — Interaction to Next Paint

How quickly does the page respond to user input?

Target: ≤ 200ms

INP measures the delay between a user interaction (click, tap, keyboard) and the next visual update. High INP makes the UI feel sluggish or frozen.

Common causes and fixes:

CauseFix
Heavy JS on main threadBreak into smaller tasks, use requestIdleCallback
Large event handlersDebounce/throttle scroll and resize handlers
Synchronous DOM updatesBatch DOM writes with requestAnimationFrame
Third-party scripts blockingLoad third-party scripts with async or defer
React re-rendersMemoize with useMemo, useCallback, React.memo

Images

Images are the single biggest performance lever on most pages.

<!-- Modern formats with fallback -->
<picture>
  <source srcset="image.avif" type="image/avif">
  <source srcset="image.webp" type="image/webp">
  <img src="image.jpg" width="800" height="600" alt="..." loading="lazy">
</picture>

<!-- Responsive images -->
<img
  srcset="image-400.webp 400w, image-800.webp 800w, image-1200.webp 1200w"
  sizes="(max-width: 600px) 100vw, 50vw"
  src="image-800.webp"
  alt="..."
  width="800"
  height="600"
  loading="lazy"
>

Rules:

  • Always set width and height — prevents CLS
  • Use loading="lazy" below the fold, never on LCP image
  • Serve WebP or AVIF — typically 30–50% smaller than JPEG
  • Size images to their display size — do not serve 2000px image for a 400px slot
  • Use a CDN with automatic format conversion where possible

Fonts

Web fonts block rendering if not handled correctly.

<!-- Preconnect to font origin -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- Preload critical font file -->
<link rel="preload" href="/fonts/brand.woff2" as="font" type="font/woff2" crossorigin>
@font-face {
  font-family: 'Brand';
  src: url('/fonts/brand.woff2') format('woff2');
  font-display: swap;     /* show fallback immediately, swap when loaded */
  /* font-display: optional; — never swap, use fallback if not cached */
}
  • font-display: swap — good for headings, acceptable CLS
  • font-display: optional — zero CLS, font only used if cached (best for body text)
  • Subset fonts to the characters actually used — reduces file size by 60–80%

JavaScript

<!-- Defer non-critical scripts -->
<script src="analytics.js" defer></script>
<script src="chat-widget.js" async></script>

<!-- Module scripts are deferred by default -->
<script type="module" src="app.js"></script>
  • defer: executes after HTML parsed, in order — use for most scripts
  • async: executes as soon as downloaded, out of order — use for independent scripts (analytics)
  • Never block the main thread with synchronous <script> in <head>

Lighthouse CI (automated audits)

Run Lighthouse in CI to catch regressions before deployment.

# Install
npm install -g @lhci/cli

# Run
lhci autorun --upload.target=temporary-public-storage
# .lighthouserc.json
{
  "ci": {
    "assert": {
      "assertions": {
        "categories:performance": ["warn", { "minScore": 0.9 }],
        "categories:accessibility": ["error", { "minScore": 1.0 }],
        "categories:seo": ["warn", { "minScore": 0.95 }]
      }
    }
  }
}

Review Checklist

  • Lighthouse performance score ≥ 90
  • Lighthouse accessibility score = 100
  • LCP ≤ 2.5s — LCP image preloaded, no loading="lazy" on it
  • CLS ≤ 0.1 — all images have width and height, no layout-shifting animations
  • INP ≤ 200ms — no heavy synchronous JS on main thread
  • Images served as WebP or AVIF with correct dimensions
  • loading="lazy" on all below-fold images
  • Web fonts use font-display: swap or optional
  • Non-critical JS loaded with defer or async
  • Lighthouse CI configured to catch regressions in deployment pipeline

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Derive a full UI palette from one or two brand colours — state variants, brand-tinted greys, semantic colours. Use when building or expanding a colour system.

The English summary is being prepared. Showing the original description.

dembrandt/dembrandt-skills151Updated Oct 22, 2026

Top bar, sidebar rail, app launcher, tenant and environment cue, status bar. Use when designing the persistent shell, a collapsible sidebar, or navigation between apps behind one login.

The English summary is being prepared. Showing the original description.

dembrandt/dembrandt-skills151Updated Oct 22, 2026

Product visuals must show the real product with real data. Use when building landing pages, hero sections, screenshots or demo panels.

The English summary is being prepared. Showing the original description.

dembrandt/dembrandt-skills151Updated Oct 22, 2026

Shape language across type, radius and icons carries brand personality. Use when starting a design system, picking icons or radius tokens, or reviewing visual consistency.

The English summary is being prepared. Showing the original description.

dembrandt/dembrandt-skills151Updated Oct 22, 2026

Rest, hover, active, focus, disabled and loading states, derived from the base colour. Use when designing buttons, links, inputs or any clickable component.

The English summary is being prepared. Showing the original description.

dembrandt/dembrandt-skills151Updated Oct 22, 2026

Rebuild a live web page 1:1 from measurement into Figma, Penpot or code, then verify it. Use when reproducing a page or checking a rebuild against the original.

The English summary is being prepared. Showing the original description.

dembrandt/dembrandt-skills151Updated Oct 22, 2026

See all skills by dembrandt

Report a problem with this skill