
Web Performance Optimization
- 434 installs
- 305 repo stars
- Updated March 4, 2026
- aj-geddes/useful-ai-prompts
web-performance-optimization is an agent skill that audits and optimizes Core Web Vitals, JavaScript bundle weight, caching, and render paths for developers shipping fast web pages.
About
web-performance-optimization is an agent skill from aj-geddes/useful-ai-prompts for improving front-end load performance before launch. It guides audits of Core Web Vitals—LCP, INP, and CLS—plus JavaScript bundle weight, HTTP caching, CDN configuration, and critical render paths on mobile networks. Use it when Lighthouse or Search Console flags regressions, conversion drops trace to slow first paint, or SEO ranking depends on passing CWV thresholds. The skill connects measurement to concrete fixes: code splitting, lazy loading, cache headers, font and image delivery, and eliminating render-blocking resources rather than generic best-practice lists.
- Core Web Vitals audit prompts
- Bundle and lazy-load tactics
- Image and font optimization
- Caching and CDN guidance
- Lab versus field measurement
Web Performance Optimization by the numbers
- 434 all-time installs (skills.sh)
- Ranked #648 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/aj-geddes/useful-ai-prompts --skill web-performance-optimizationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 434 |
|---|---|
| repo stars | ★ 305 |
| Last updated | March 4, 2026 |
| Repository | aj-geddes/useful-ai-prompts ↗ |
How do you improve Core Web Vitals before launch?
Audit and optimize Core Web Vitals, bundle weight, caching, and render paths so pages load fast on mobile networks and meet SEO and conversion expectations before launch.
Who is it for?
Front-end developers shipping marketing or app pages that must pass Core Web Vitals on mobile networks and meet SEO performance expectations.
Skip if: Pure backend API latency tuning with no browser render path or asset delivery involved.
When should I use this skill?
Lighthouse scores drop, Search Console reports CWV failures, or a developer asks to reduce bundle weight and improve LCP before release.
What you get
Performance audit notes, bundle reduction plan, caching configuration, and Core Web Vitals remediation checklist
- CWV audit report
- Bundle optimization plan
- Caching configuration
Files
Web Performance Optimization
Table of Contents
Overview
Implement performance optimization strategies including lazy loading, code splitting, caching, compression, and monitoring to improve Core Web Vitals and user experience.
When to Use
- Slow page load times
- High Largest Contentful Paint (LCP)
- Large bundle sizes
- Frequent Cumulative Layout Shift (CLS)
- Mobile performance issues
Quick Start
Minimal working example:
// utils/lazyLoad.ts
import React from 'react';
export const lazyLoad = (importStatement: Promise<any>) => {
return React.lazy(() =>
importStatement.then(module => ({
default: module.default
}))
);
};
// routes.tsx
import { lazyLoad } from './utils/lazyLoad';
export const routes = [
{
path: '/',
component: () => import('./pages/Home'),
lazy: lazyLoad(import('./pages/Home'))
},
{
path: '/dashboard',
lazy: lazyLoad(import('./pages/Dashboard'))
},
{
// ... (see reference guides for full implementation)Reference Guides
Detailed implementations in the references/ directory:
| Guide | Contents |
|---|---|
| Code Splitting and Lazy Loading (React) | Code Splitting and Lazy Loading (React) |
| Image Optimization | Image Optimization |
| HTTP Caching and Service Workers | HTTP Caching and Service Workers |
| Gzip Compression and Asset Optimization | Gzip Compression and Asset Optimization |
| Performance Monitoring | Performance Monitoring |
Best Practices
✅ DO
- Follow established patterns and conventions
- Write clean, maintainable code
- Add appropriate documentation
- Test thoroughly before deploying
❌ DON'T
- Skip testing or validation
- Ignore error handling
- Hard-code configuration values
Code Splitting and Lazy Loading (React)
Code Splitting and Lazy Loading (React)
// utils/lazyLoad.ts
import React from 'react';
export const lazyLoad = (importStatement: Promise<any>) => {
return React.lazy(() =>
importStatement.then(module => ({
default: module.default
}))
);
};
// routes.tsx
import { lazyLoad } from './utils/lazyLoad';
export const routes = [
{
path: '/',
component: () => import('./pages/Home'),
lazy: lazyLoad(import('./pages/Home'))
},
{
path: '/dashboard',
lazy: lazyLoad(import('./pages/Dashboard'))
},
{
path: '/users',
lazy: lazyLoad(import('./pages/Users'))
}
];
// App.tsx with Suspense
import { Suspense } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
export const App = () => {
return (
<BrowserRouter>
<Suspense fallback={<LoadingSpinner />}>
<Routes>
{routes.map(route => (
<Route key={route.path} path={route.path} element={<route.lazy />} />
))}
</Routes>
</Suspense>
</BrowserRouter>
);
};
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10
},
common: {
minChunks: 2,
priority: 5,
reuseExistingChunk: true
}
}
}
}
};Gzip Compression and Asset Optimization
Gzip Compression and Asset Optimization
// webpack.config.js with compression
const CompressionPlugin = require('compression-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
mode: 'production',
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true
}
}
})
]
},
plugins: [
new CompressionPlugin({
algorithm: 'gzip',
test: /\.(js|css|html|svg)$/,
threshold: 8192,
minRatio: 0.8
})
]
};
// .htaccess (Apache)
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
</IfModule>
# nginx.conf
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length 1000;
gzip_proxied any;HTTP Caching and Service Workers
HTTP Caching and Service Workers
// service-worker.ts
const CACHE_NAME = "v1";
const ASSETS_TO_CACHE = ["/", "/index.html", "/css/style.css", "/js/app.js"];
self.addEventListener("install", (event: ExtendableEvent) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(ASSETS_TO_CACHE);
}),
);
});
self.addEventListener("fetch", (event: FetchEvent) => {
// Cache first, fall back to network
event.respondWith(
caches.match(event.request).then((response) => {
if (response) return response;
return fetch(event.request)
.then((response) => {
// Clone the response
const cloned = response.clone();
// Cache successful responses
if (response.status === 200) {
caches.open(CACHE_NAME).then((cache) => {
cache.put(event.request, cloned);
});
}
return response;
})
.catch(() => {
// Return offline page if available
return caches.match("/offline.html");
});
}),
);
});
// Register service worker
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker
.register("/service-worker.js")
.catch((err) => console.error("SW registration failed:", err));
});
}Image Optimization
Image Optimization
<!-- Picture element with srcset for responsive images -->
<picture>
<source
media="(min-width: 1024px)"
srcset="image-large.jpg, image-large@2x.jpg 2x"
/>
<source
media="(min-width: 640px)"
srcset="image-medium.jpg, image-medium@2x.jpg 2x"
/>
<source srcset="image-small.jpg, image-small@2x.jpg 2x" />
<img src="image-fallback.jpg" alt="Description" loading="lazy" />
</picture>
<!-- WebP format with fallback -->
<picture>
<source srcset="image.webp" type="image/webp" />
<img src="image.jpg" alt="Description" loading="lazy" />
</picture>
<!-- TypeScript Image Component -->
<script lang="typescript">
interface ImageProps {
src: string;
alt: string;
width: number;
height: number;
sizes?: string;
loading?: "lazy" | "eager";
}
const OptimizedImage: React.FC<ImageProps> = ({
src,
alt,
width,
height,
sizes = "100vw",
loading = "lazy",
}) => {
const webpSrc = src.replace(/\.(jpg|png)$/, ".webp");
return (
<picture>
<source srcSet={webpSrc} type="image/webp" />
<img
src={src}
alt={alt}
width={width}
height={height}
sizes={sizes}
loading={loading}
decoding="async"
/>
</picture>
);
};
</script>Performance Monitoring
Performance Monitoring
// utils/performanceMonitor.ts
interface PerformanceMetrics {
fcp: number; // First Contentful Paint
lcp: number; // Largest Contentful Paint
cls: number; // Cumulative Layout Shift
fid: number; // First Input Delay
ttfb: number; // Time to First Byte
}
export const observeWebVitals = (
callback: (metrics: Partial<PerformanceMetrics>) => void,
) => {
const metrics: Partial<PerformanceMetrics> = {};
// LCP
const lcpObserver = new PerformanceObserver((list) => {
const entries = list.getEntries();
const lastEntry = entries[entries.length - 1];
metrics.lcp = lastEntry.renderTime || lastEntry.loadTime;
callback(metrics);
});
try {
lcpObserver.observe({ entryTypes: ["largest-contentful-paint"] });
} catch (e) {
console.warn("LCP observer not supported");
}
// CLS
const clsObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (!(entry as any).hadRecentInput) {
metrics.cls = (metrics.cls || 0) + (entry as any).value;
callback(metrics);
}
}
});
try {
clsObserver.observe({ entryTypes: ["layout-shift"] });
} catch (e) {
console.warn("CLS observer not supported");
}
// FID via INP
const inputObserver = new PerformanceObserver((list) => {
const entries = list.getEntries();
const firstEntry = entries[0];
metrics.fid = firstEntry.processingDuration;
callback(metrics);
});
try {
inputObserver.observe({ entryTypes: ["first-input", "event"] });
} catch (e) {
console.warn("FID observer not supported");
}
// TTFB
const navigationTiming = performance.getEntriesByType("navigation")[0];
if (navigationTiming) {
metrics.ttfb =
(navigationTiming as any).responseStart -
(navigationTiming as any).requestStart;
callback(metrics);
}
};
// Usage
observeWebVitals((metrics) => {
console.log("Performance metrics:", metrics);
// Send to analytics
fetch("/api/metrics", {
method: "POST",
body: JSON.stringify(metrics),
});
});
// Chrome DevTools Protocol for performance testing
import puppeteer from "puppeteer";
async function measurePagePerformance(url: string) {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url, { waitUntil: "networkidle2" });
const metrics = JSON.parse(
await page.evaluate(() => JSON.stringify(window.performance)),
);
console.log(
"Page Load Time:",
metrics.timing.loadEventEnd - metrics.timing.navigationStart,
);
console.log(
"DOM Content Loaded:",
metrics.timing.domContentLoadedEventEnd - metrics.timing.navigationStart,
);
await browser.close();
}// Component: [Name]
// TODO: Customize for your framework (React, Vue, Svelte, etc.)
import React from 'react';
interface Props {
// TODO: Define props
}
export function ComponentName({ }: Props) {
// TODO: Add state and effects
return (
<div>
{/* TODO: Add component markup */}
</div>
);
}
Related skills
How it compares
Use web-performance-optimization for browser CWV and asset delivery; pair with backend skills only when API latency—not render path—is the bottleneck.
FAQ
What metrics does web-performance-optimization focus on?
web-performance-optimization centers on Core Web Vitals—Largest Contentful Paint, Interaction to Next Paint, and Cumulative Layout Shift—alongside JavaScript bundle weight, HTTP caching, and render-blocking resource removal.
When should web-performance-optimization run?
web-performance-optimization fits pre-launch audits when Lighthouse or Search Console flags CWV regressions, or when mobile load times threaten SEO rankings and conversion rates on slow networks.