Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
oimiragieo avatar

Web Perf

  • 29 installs
  • 36 repo stars
  • Updated July 14, 2026
  • oimiragieo/agent-studio

Helps with ai & agent building tasks.

About

web-perf is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.

  • web-perf
  • AI & Agent Building
  • AI-coding skill

Web Perf by the numbers

  • 29 all-time installs (skills.sh)
  • Ranked #9,417 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Jul 31, 2026 (Skillselion catalog sync)
npx skills add https://github.com/oimiragieo/agent-studio --skill web-perf

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs29
repo stars36
Last updatedJuly 14, 2026
Repositoryoimiragieo/agent-studio

What it does

Helps with ai & agent building tasks.

Files

SKILL.mdMarkdownGitHub ↗

Web Performance Audit

Structured 5-phase web performance audit workflow. Diagnose performance bottlenecks, measure Core Web Vitals, and produce actionable optimization recommendations.

When to Apply

Use this skill when:

  • Auditing website performance for Core Web Vitals compliance
  • Diagnosing slow page loads, high Time to Interactive, or layout shifts
  • Optimizing Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), or Interaction to Next Paint (INP)
  • Reviewing frontend code for performance anti-patterns
  • Preparing a site for Google's page experience ranking signals
  • Optimizing build output for Webpack, Vite, Next.js, or Nuxt

Core Web Vitals Thresholds

MetricGoodNeeds ImprovementPoorWhat It Measures
LCP<= 2.5s2.5s - 4.0s> 4.0sLoading performance
CLS<= 0.10.1 - 0.25> 0.25Visual stability
INP<= 200ms200ms - 500ms> 500msInteractivity (replaced FID)

Additional Performance Metrics

MetricGoodPoorWhat It Measures
FCP<= 1.8s> 3.0sFirst content rendered
TTFB<= 800ms> 1800msServer response time
TBT<= 200ms> 600msMain thread blocking
Speed Index<= 3.4s> 5.8sVisual completeness over time

5-Phase Audit Workflow

Phase 1: Performance Trace

Capture a performance trace to establish baseline metrics.

Browser-Based (Chrome DevTools):

1. Open Chrome DevTools (F12) > Performance tab 2. Click "Record" and reload the page 3. Stop recording after page fully loads 4. Analyze the flame chart for:

  • Long tasks (> 50ms, marked in red)
  • Layout thrashing (forced reflow cycles)
  • Render-blocking resources
  • JavaScript execution bottlenecks

Lighthouse Audit:

# CLI-based Lighthouse audit
npx lighthouse https://example.com --output=json --output-path=./lighthouse-report.json

# With specific categories
npx lighthouse https://example.com --only-categories=performance --output=html

# Mobile simulation (default)
npx lighthouse https://example.com --preset=perf --throttling-method=simulate

Key Trace Indicators:

  • Main thread busy time: Should be < 4s total
  • Largest task duration: Should be < 250ms
  • Script evaluation time: Should be < 2s
  • Layout/style recalculation: Should be < 500ms

Phase 2: Core Web Vitals Analysis

Measure each Core Web Vital and identify specific causes.

LCP Diagnosis

LCP measures loading performance -- when the largest content element becomes visible.

Common LCP Elements:

  • <img> elements (hero images)
  • <video> poster images
  • Block-level elements with background images
  • Text blocks (<h1>, <p>)

LCP Optimization Checklist:

1. Preload the LCP resource

   <link rel="preload" as="image" href="/hero.webp" fetchpriority="high" />

2. Eliminate render-blocking resources

   <!-- Defer non-critical CSS -->
   <link rel="stylesheet" href="/non-critical.css" media="print" onload="this.media='all'" />

   <!-- Async non-critical JS -->
   <script src="/analytics.js" async></script>

3. Optimize server response time (TTFB)

  • Use CDN for static assets
  • Enable HTTP/2 or HTTP/3
  • Implement server-side caching
  • Use streaming SSR where supported

4. Optimize image delivery

   <!-- Modern format with fallback -->
   <picture>
     <source srcset="/hero.avif" type="image/avif" />
     <source srcset="/hero.webp" type="image/webp" />
     <img
       src="/hero.jpg"
       alt="Hero"
       width="1200"
       height="600"
       fetchpriority="high"
       decoding="async"
     />
   </picture>
CLS Diagnosis

CLS measures visual stability -- unexpected layout shifts during page load.

Common CLS Causes:

  • Images without explicit dimensions
  • Ads or embeds without reserved space
  • Dynamically injected content above the fold
  • Web fonts causing FOIT/FOUT (Flash of Invisible/Unstyled Text)

CLS Optimization Checklist:

1. Always set image dimensions

   <img src="/photo.jpg" width="800" height="600" alt="Photo" />

Or use CSS aspect-ratio:

   .hero-image {
     aspect-ratio: 16 / 9;
     width: 100%;
   }

2. Reserve space for dynamic content

   .ad-slot {
     min-height: 250px;
   }
   .skeleton {
     height: 200px;
     background: #f0f0f0;
   }

3. Use `font-display: swap` with size-adjust

   @font-face {
     font-family: 'CustomFont';
     src: url('/font.woff2') format('woff2');
     font-display: swap;
     size-adjust: 100.5%; /* Match fallback font metrics */
   }

4. Avoid inserting content above existing content

  • Banners should push down from top, not shift existing content
  • Use transform animations instead of top/left/width/height
INP Diagnosis

INP measures interactivity -- the delay between user interaction and visual response.

Common INP Causes:

  • Long JavaScript tasks blocking the main thread
  • Synchronous layout/style recalculations
  • Heavy event handlers
  • Excessive re-renders (React, Vue)

INP Optimization Checklist:

1. Break up long tasks

   // Instead of one long task
   function processAllItems(items) {
     for (const item of items) {
       /* heavy work */
     }
   }

   // Break into chunks with scheduler
   async function processAllItems(items) {
     for (const item of items) {
       processItem(item);
       // Yield to main thread between items
       await scheduler.yield();
     }
   }

2. Debounce/throttle event handlers

   // Throttle scroll handler
   let ticking = false;
   window.addEventListener(
     'scroll',
     () => {
       if (!ticking) {
         requestAnimationFrame(() => {
           updateUI();
           ticking = false;
         });
         ticking = true;
       }
     },
     { passive: true }
   );

3. Use `requestIdleCallback` for non-urgent work

   requestIdleCallback(() => {
     // Analytics, prefetching, non-visible updates
     sendAnalytics(data);
   });

Phase 3: Network Analysis

Analyze network waterfall for optimization opportunities.

Key Checks:

1. Resource count and total size

  • Target: < 100 requests, < 2MB total (compressed)
  • Check: performance.getEntriesByType('resource').length

2. Critical request chains

  • Identify chains longer than 3 requests
  • Break chains with preload/prefetch hints

3. Compression

  • All text resources should use Brotli (br) or gzip
  • Check Content-Encoding header in response

4. Caching headers

   # Immutable assets (hashed filenames)
   Cache-Control: public, max-age=31536000, immutable

   # HTML documents
   Cache-Control: no-cache

   # API responses
   Cache-Control: private, max-age=0, must-revalidate

5. HTTP/2+ multiplexing

  • Verify protocol in DevTools Network tab
  • Multiple resources should load in parallel over single connection

Phase 4: Accessibility Performance

Performance optimizations must not degrade accessibility.

Validation Checklist:

  • [ ] Lazy-loaded images have alt attributes
  • [ ] Deferred scripts do not break keyboard navigation
  • [ ] Skeleton loaders have aria-busy="true" and aria-label
  • [ ] prefers-reduced-motion is respected for animations
  • [ ] Focus management works with dynamically loaded content
/* Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

Phase 5: Codebase Analysis

Review source code for performance anti-patterns.

Webpack Optimization
// webpack.config.js
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      maxInitialRequests: 25,
      minSize: 20000,
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name(module) {
            const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
            return `vendor.${packageName.replace('@', '')}`;
          },
        },
      },
    },
  },
};
Vite Optimization
// vite.config.ts
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'],
          router: ['react-router-dom'],
        },
      },
    },
    cssCodeSplit: true,
    sourcemap: false, // Disable in production
  },
});
Next.js Optimization
// next.config.ts
const nextConfig = {
  images: {
    formats: ['image/avif', 'image/webp'],
    deviceSizes: [640, 750, 828, 1080, 1200],
  },
  experimental: {
    optimizePackageImports: ['lucide-react', '@heroicons/react'],
  },
};
Common Code Anti-Patterns
Anti-PatternImpactFix
Barrel file importsBundle bloatImport directly from module
Synchronous localStorage in renderMain thread blockMove to useEffect or worker
Unoptimized imagesLCP, bandwidthUse next/image or <picture>
Inline <script> in bodyRender blockingUse async or defer
CSS @import chainsCSSOM blockingConcatenate or inline critical CSS
Unthrottled scroll listenersINPUse passive: true + requestAnimationFrame
document.querySelectorAll in loopsLayout thrashingCache DOM references

Audit Report Template

# Web Performance Audit Report

**URL:** [target URL]
**Date:** [audit date]
**Tool:** Lighthouse [version] / Chrome DevTools

## Core Web Vitals Summary

| Metric | Score | Rating                      | Target   |
| ------ | ----- | --------------------------- | -------- |
| LCP    | X.Xs  | GOOD/NEEDS IMPROVEMENT/POOR | <= 2.5s  |
| CLS    | X.XX  | GOOD/NEEDS IMPROVEMENT/POOR | <= 0.1   |
| INP    | Xms   | GOOD/NEEDS IMPROVEMENT/POOR | <= 200ms |
| FCP    | X.Xs  | -                           | <= 1.8s  |
| TTFB   | Xms   | -                           | <= 800ms |
| TBT    | Xms   | -                           | <= 200ms |

## Critical Findings

### P0 (Immediate Action Required)

1. [Finding] - [Impact] - [Recommended Fix]

### P1 (Address This Sprint)

1. [Finding] - [Impact] - [Recommended Fix]

### P2 (Address This Quarter)

1. [Finding] - [Impact] - [Recommended Fix]

## Optimization Recommendations (Priority Order)

1. [Recommendation with estimated impact]
2. [Recommendation with estimated impact]
3. [Recommendation with estimated impact]

Anti-Patterns

  • Do NOT optimize without measuring first -- always capture baseline metrics
  • Do NOT lazy-load above-the-fold content -- it worsens LCP
  • Do NOT remove image dimensions to "fix" CLS -- use CSS aspect-ratio instead
  • Do NOT bundle all JS into a single file -- use code splitting
  • Do NOT ignore mobile performance -- test with CPU/network throttling
  • Do NOT use loading="lazy" on the LCP image -- it delays loading
  • Do NOT serve images without modern formats (AVIF/WebP)

References

Iron Laws

1. ALWAYS measure Core Web Vitals (LCP, INP, CLS) with field data (CrUX) before proposing optimizations 2. NEVER optimize based on lab data alone — real user metrics determine actual user experience 3. ALWAYS prioritize LCP ≤2.5s, INP ≤200ms, CLS ≤0.1 as the primary performance targets 4. NEVER ship a performance fix without a before/after measurement proving improvement 5. ALWAYS address critical rendering path issues before layout or paint optimizations

Anti-Patterns

Anti-PatternWhy It FailsCorrect Approach
Optimizing without baseline measurementCan't prove improvement, may optimize wrong thingMeasure CWV with Lighthouse and CrUX first
Lab-only metrics (Lighthouse only)Doesn't reflect real user network/device conditionsCombine lab data with CrUX field data
Fixing CLS before LCP is addressedLCP impacts far more users than CLSPrioritize in order: LCP → INP → CLS
Shipping without before/after metricsNo evidence of improvement for stakeholdersRecord pre-fix and post-fix CWV scores
Adding polyfills without code splittingBloats JS bundle for all usersUse dynamic import() with target browserslist

Memory Protocol (MANDATORY)

Before starting: Read .claude/context/memory/learnings.md

After completing:

  • New pattern -> .claude/context/memory/learnings.md
  • Issue found -> .claude/context/memory/issues.md
  • Decision made -> .claude/context/memory/decisions.md

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.