performance-opt

Performance Optimization Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "performance-opt" with this command: npx skills add sgcarstrends/sgcarstrends/sgcarstrends-sgcarstrends-performance-opt

Performance Optimization Skill

This skill helps you identify and fix performance bottlenecks across the platform.

When to Use This Skill

  • Investigating slow page loads

  • Optimizing bundle size

  • Reducing API response times

  • Improving database query performance

  • Optimizing React re-renders

  • Before production deployments

Performance Metrics

Web Vitals (Next.js)

Core Web Vitals:

  • LCP (Largest Contentful Paint): < 2.5s

  • FID (First Input Delay): < 100ms

  • CLS (Cumulative Layout Shift): < 0.1

Other Metrics:

  • FCP (First Contentful Paint): < 1.8s

  • TTFB (Time to First Byte): < 600ms

  • TTI (Time to Interactive): < 3.8s

Measure Performance

Run Lighthouse

npx lighthouse https://sgcarstrends.com --view

Or use Chrome DevTools:

1. Open DevTools

2. Lighthouse tab

3. Generate report

Bundle Size Optimization

Analyze Bundle

Next.js bundle analyzer

cd apps/web

Add to next.config.js temporarily

ANALYZE=true pnpm build

Or use bundle-analyzer package

pnpm add -D @next/bundle-analyzer

View analysis

open .next/analyze/client.html

Reduce Bundle Size

  1. Dynamic Imports

// ❌ Static import (loads immediately) import { HeavyComponent } from "./heavy-component";

export default function Page() { return <HeavyComponent />; }

// ✅ Dynamic import (lazy load) import dynamic from "next/dynamic";

const HeavyComponent = dynamic(() => import("./heavy-component"), { loading: () => <div>Loading...</div>, ssr: false, // Disable SSR if not needed });

export default function Page() { return <HeavyComponent />; }

  1. Tree Shaking

// ❌ Imports entire library import _ from "lodash"; const result = _.uniq(array);

// ✅ Import only what you need import uniq from "lodash/uniq"; const result = uniq(array);

// ✅ Or use modern alternative const result = [...new Set(array)];

  1. Optimize Dependencies

Find large dependencies

npx npkill

Or analyze with bundlephobia

Visit: https://bundlephobia.com

Replace large libs with smaller alternatives:

moment.js (70kb) → date-fns (13kb) or dayjs (2kb)

lodash (71kb) → lodash-es + tree shaking

  1. Code Splitting

// Split by route (automatic in Next.js) // Each page is a separate chunk

// Split by component const AdminPanel = dynamic(() => import("./admin-panel"));

// Split by condition const Chart = dynamic(() => import(userPreference === "advanced" ? "./advanced-chart" : "./simple-chart") );

React Performance

Prevent Unnecessary Re-renders

  1. useMemo

// ❌ Recalculates on every render function Component({ data }) { const processed = expensiveOperation(data); return <div>{processed}</div>; }

// ✅ Memoized calculation function Component({ data }) { const processed = useMemo( () => expensiveOperation(data), [data] ); return <div>{processed}</div>; }

  1. useCallback

// ❌ New function on every render function Parent() { return <Child onClick={() => console.log("clicked")} />; }

// ✅ Memoized function function Parent() { const handleClick = useCallback(() => { console.log("clicked"); }, []);

return <Child onClick={handleClick} />; }

  1. React.memo

// ❌ Re-renders even when props unchanged function ChildComponent({ name }) { return <div>{name}</div>; }

// ✅ Only re-renders when props change const ChildComponent = React.memo(function ChildComponent({ name }) { return <div>{name}</div>; });

Virtualize Long Lists

Install virtualization library

pnpm add -D react-window

import { FixedSizeList } from "react-window";

// ❌ Renders all items (slow for 1000+ items) function CarList({ cars }) { return ( <div> {cars.map(car => <CarCard key={car.id} car={car} />)} </div> ); }

// ✅ Only renders visible items function CarList({ cars }) { const Row = ({ index, style }) => ( <div style={style}> <CarCard car={cars[index]} /> </div> );

return ( <FixedSizeList height={600} itemCount={cars.length} itemSize={100} width="100%" > {Row} </FixedSizeList> ); }

Debounce User Input

import { useDeferredValue, useState } from "react";

function SearchComponent() { const [input, setInput] = useState(""); const deferredInput = useDeferredValue(input); // Defers update

return ( <> <input value={input} onChange={(e) => setInput(e.target.value)} /> <SearchResults query={deferredInput} /> </> ); }

Database Query Optimization

Identify Slow Queries

// Add query timing const start = Date.now(); const result = await db.query.cars.findMany(); const duration = Date.now() - start;

if (duration > 100) { console.warn(Slow query: ${duration}ms); }

Optimize Queries

  1. Add Indexes

// packages/database/src/db/schema/cars.ts import { pgTable, text, index } from "drizzle-orm/pg-core";

export const cars = pgTable("cars", { id: text("id").primaryKey(), make: text("make").notNull(), month: text("month").notNull(), }, (table) => ({ // Add indexes for frequently queried columns makeIdx: index("cars_make_idx").on(table.make), monthIdx: index("cars_month_idx").on(table.month), }));

  1. Avoid N+1 Queries

// ❌ N+1 queries (slow) const posts = await db.query.posts.findMany(); for (const post of posts) { post.author = await db.query.users.findFirst({ where: eq(users.id, post.authorId), }); }

// ✅ Single query with join (fast) const posts = await db.query.posts.findMany({ with: { author: true, }, });

  1. Select Only Needed Columns

// ❌ Selects all columns const users = await db.query.users.findMany();

// ✅ Select only what's needed const users = await db .select({ id: users.id, name: users.name, email: users.email, }) .from(users);

  1. Use Pagination

// ❌ Loads all records const cars = await db.query.cars.findMany();

// ✅ Paginated query const cars = await db.query.cars.findMany({ limit: 20, offset: (page - 1) * 20, });

  1. Batch Queries

// ❌ Multiple separate queries const user1 = await db.query.users.findFirst({ where: eq(users.id, "1") }); const user2 = await db.query.users.findFirst({ where: eq(users.id, "2") }); const user3 = await db.query.users.findFirst({ where: eq(users.id, "3") });

// ✅ Single batched query const userIds = ["1", "2", "3"]; const users = await db.query.users.findMany({ where: inArray(users.id, userIds), });

Caching Strategies

Server-Side Caching

import { redis } from "@sgcarstrends/utils";

export async function getCarsWithCache(make: string) { const cacheKey = cars:${make};

// Check cache const cached = await redis.get(cacheKey); if (cached) { return JSON.parse(cached as string); }

// Fetch from database const cars = await db.query.cars.findMany({ where: eq(cars.make, make), });

// Cache for 1 hour await redis.set(cacheKey, JSON.stringify(cars), { ex: 3600 });

return cars; }

Next.js Caching

// Cache with revalidation export const revalidate = 3600; // Revalidate every hour

export async function getData() { const res = await fetch("https://api.example.com/data", { next: { revalidate: 3600 }, }); return res.json(); }

// Cache indefinitely, revalidate on demand export const dynamic = "force-static";

export async function getStaticData() { // This data is cached until manually revalidated const data = await db.query.cars.findMany(); return data; }

Image Optimization

Use Next.js Image Component

import Image from "next/image";

// ❌ Regular img tag <img src="/logo.png" alt="Logo" />

// ✅ Optimized image <Image src="/logo.png" alt="Logo" width={200} height={200} priority // For above-the-fold images />

// ✅ Responsive image <Image src="/hero.jpg" alt="Hero" fill sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw" priority />

Image Formats

// Use modern formats <Image src="/image.webp" // WebP for smaller size alt="Image" width={800} height={600} />

// Automatic format optimization with Next.js Image // Next.js automatically serves WebP/AVIF when supported

API Performance

Response Time Optimization

// Add response time logging app.use(async (c, next) => { const start = Date.now(); await next(); const duration = Date.now() - start;

c.header("X-Response-Time", ${duration}ms);

if (duration > 500) { console.warn(Slow endpoint: ${c.req.path} (${duration}ms)); } });

Compression

// Enable compression in Hono import { compress } from "hono/compress";

const app = new Hono(); app.use("*", compress());

Pagination

// Implement cursor-based pagination export async function getCars(cursor?: string, limit = 20) { const query = db.query.cars.findMany({ limit: limit + 1, // Fetch one extra to determine if there's more orderBy: desc(cars.createdAt), });

if (cursor) { query.where(lt(cars.id, cursor)); }

const results = await query; const hasMore = results.length > limit; const items = hasMore ? results.slice(0, -1) : results;

return { items, nextCursor: hasMore ? items[items.length - 1].id : null, }; }

Lambda Performance

Cold Start Optimization

// infra/api.ts export function API({ stack, app }: StackContext) { const api = new Function(stack, "api", { handler: "apps/api/src/index.handler", runtime: "nodejs20.x", architecture: "arm64", // Graviton2 for better performance memory: 1024, // More memory = faster CPU nodejs: { esbuild: { minify: true, // Smaller bundle = faster cold starts bundle: true, }, }, }); }

Provisioned Concurrency

For production with consistent traffic:

const api = new Function(stack, "api", { handler: "apps/api/src/index.handler", reservedConcurrentExecutions: 10, // Reserve instances });

Performance Monitoring

Web Vitals in Next.js

// app/layout.tsx import { SpeedInsights } from "@vercel/speed-insights/next";

export default function RootLayout({ children }) { return ( <html> <body> {children} <SpeedInsights /> </body> </html> ); }

Custom Performance Marks

export async function performanceTracked Operation() { performance.mark("operation-start");

await doSomething();

performance.mark("operation-end"); performance.measure("operation", "operation-start", "operation-end");

const measure = performance.getEntriesByName("operation")[0]; console.log(Operation took ${measure.duration}ms); }

Performance Testing

Load Testing

Install Apache Bench

or use k6, Artillery, etc.

Test API endpoint

ab -n 1000 -c 10 https://api.sgcarstrends.com/health

With k6

k6 run loadtest.js

Performance Benchmarks

// tests/performance/database.test.ts import { performance } from "perf_hooks";

describe("Database Performance", () => { it("queries cars in < 100ms", async () => { const start = performance.now();

await db.query.cars.findMany({ limit: 100 });

const duration = performance.now() - start;
expect(duration).toBeLessThan(100);

}); });

Performance Checklist

  • Bundle size < 200KB (initial load)

  • LCP < 2.5s

  • FID < 100ms

  • CLS < 0.1

  • API responses < 500ms

  • Database queries < 100ms

  • Images optimized (WebP/AVIF)

  • Code splitting implemented

  • Lazy loading for heavy components

  • Caching strategy in place

  • Long lists virtualized

  • Compression enabled

  • Indexes on frequently queried columns

Quick Wins

  • Enable Compression: Instant 60-80% size reduction

  • Add Image Optimization: Use Next.js Image component

  • Implement Caching: Cache expensive operations

  • Add Indexes: Speed up database queries

  • Code Splitting: Lazy load heavy components

  • Tree Shaking: Import only what you need

  • Memoization: Prevent unnecessary calculations

References

Best Practices

  • Measure First: Use profiling before optimizing

  • Focus on Impact: Optimize bottlenecks, not everything

  • Monitor Production: Track real user performance

  • Regular Audits: Run Lighthouse monthly

  • Test Performance: Add performance tests

  • Document Optimizations: Note why and what was optimized

  • Avoid Premature Optimization: Profile first, then optimize

  • Use Tools: Leverage built-in Next.js optimizations

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

framer-motion-animations

No summary provided by upstream source.

Repository SourceNeeds Review
General

shadcn-components

No summary provided by upstream source.

Repository SourceNeeds Review
General

api-testing

No summary provided by upstream source.

Repository SourceNeeds Review
General

design-language-system

No summary provided by upstream source.

Repository SourceNeeds Review