mcpField
P
performance

performance

github.com/motormetrics开发2270 次安装2 天前更新
代码仓库

关于 performance

面向 Web 应用开发者的性能优化技能,涵盖前端、后端和数据库的测量与改进,并提供常见优化方法示例。

主要功能

  1. 01Web Vitals 与后端性能目标
  2. 02使用 Lighthouse 和 k6 测量
  3. 03代码分割与摇树优化
  4. 04React 渲染和长列表优化
  5. 05数据库查询与索引调优
  6. 06Redis 和 Next.js 缓存

适用场景

  1. 01使用 Lighthouse 审计 Web 应用
  2. 02使用 k6 对 API 进行负载测试
  3. 03减少 React 重渲染和包体积
  4. 04定位慢查询并添加索引

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/motormetrics/motormetrics --skill performance

安装后在 Claude Code 中输入/performance确认已加载。

详细介绍

性能技能

性能目标

前端(Web Vitals): LCP < 2.5s,FID < 100ms,CLS < 0.1,FCP < 1.8s,TTFB < 600ms 后端: 响应时间 < 500ms(p95),冷启动 < 2s,错误率 < 1% 数据库: 查询时间 < 100ms,缓存命中率 > 80%

衡量性能

# Lighthouse audit
npx lighthouse https://motormetrics.app --view

# Bundle analysis
cd apps/web && ANALYZE=true pnpm build

# Load test with k6
k6 run --vus 100 --duration 5m load-test.js

优化包体积

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

// ✅ Dynamic import (lazy load)
import dynamic from "next/dynamic";
const HeavyComponent = dynamic(() => import("./heavy-component"), {
  loading: () => <div>Loading...</div>,
  ssr: false,
});
Tree Shaking
// ❌ Imports entire library
import _ from "lodash";

// ✅ Import only what you need
import uniq from "lodash/uniq";

React 性能

避免重复渲染
// useMemo for expensive calculations
const processed = useMemo(() => expensiveOperation(data), [data]);

// useCallback for stable function references
const handleClick = useCallback(() => doSomething(), []);

// React.memo for pure components
const Child = React.memo(function Child({ name }) {
  return <div>{name}</div>;
});
对长列表进行虚拟化
import { FixedSizeList } from "react-window";

<FixedSizeList height={600} itemCount={items.length} itemSize={100} width="100%">
  {({ index, style }) => <Item style={style} data={items[index]} />}
</FixedSizeList>

数据库查询优化

添加索引
// packages/database/src/schema/cars.ts
export const cars = pgTable("cars", {
  make: text("make").notNull(),
  month: text("month").notNull(),
}, (table) => ({
  makeIdx: index("cars_make_idx").on(table.make),
}));
避免 N+1 查询
// ❌ N+1 queries
for (const post of posts) {
  post.author = await db.query.users.findFirst({ where: eq(users.id, post.authorId) });
}

// ✅ Single query with relation
const posts = await db.query.posts.findMany({ with: { author: true } });
仅选择所需列
// ❌ Selects all columns
const users = await db.query.users.findMany();

// ✅ Select specific columns
const users = await db.select({ id: users.id, name: users.name }).from(users);
使用分页
const cars = await db.query.cars.findMany({
  limit: 20,
  offset: (page - 1) * 20,
});

缓存

Redis 缓存
import { redis } from "@motormetrics/utils/redis";

export async function getCarsWithCache(make: string) {
  const cacheKey = `cars:${make}`;
  const cached = await redis.get(cacheKey);
  if (cached) return JSON.parse(cached as string);

  const cars = await db.query.cars.findMany({ where: eq(cars.make, make) });
  await redis.set(cacheKey, JSON.stringify(cars), { ex: 3600 });
  return cars;
}
Next.js 缓存
// Revalidate every hour
export const revalidate = 3600;

// Or use fetch with caching
const data = await fetch(url, { next: { revalidate: 3600 } });

图像优化

import Image from "next/image";

// ✅ Optimized image with priority for above-fold
<Image
  src="/hero.jpg"
  alt="Hero"
  fill
  sizes="(max-width: 768px) 100vw, 50vw"
  priority
/>

Vercel 函数优化

// API route with optimized config
export const config = {
  maxDuration: 60, // seconds
};

// Use edge functions for low-latency endpoints
export const runtime = "edge";

性能分析

性能中间件
// apps/api/src/middleware/performance.ts
export const performanceMiddleware = async (c: Context, next: Next) => {
  const start = performance.now();
  await next();
  const duration = performance.now() - start;

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

  if (duration > 1000) {
    log.warn("Slow request", { path: c.req.path, duration: Math.round(duration) });
  }
};
查询分析
const start = performance.now();
const result = await db.query.cars.findMany();
const duration = performance.now() - start;

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

在 Vercel Dashboard → Analytics 中查看:

  • 函数执行时间
  • 边缘响应时间
  • Web Vitals 指标
  • 请求量和错误

负载测试

// load-test.js (k6)
import http from "k6/http";
import { check } from "k6";

export const options = {
  stages: [
    { duration: "2m", target: 100 },
    { duration: "5m", target: 100 },
    { duration: "2m", target: 0 },
  ],
  thresholds: {
    http_req_duration: ["p(95)<500"],
    http_req_failed: ["rate<0.01"],
  },
};

export default function() {
  const res = http.get("https://api.motormetrics.app/api/v1/cars/makes");
  check(res, { "status 200": (r) => r.status === 200 });
}

性能检查清单

  • 包体积 < 200KB(初始加载)
  • LCP < 2.5s,FID < 100ms,CLS < 0.1
  • API 响应 < 500ms
  • 数据库查询 < 100ms
  • 图像已优化(WebP/AVIF)
  • 已实现代码拆分
  • 已制定缓存策略
  • 长列表已进行虚拟化
  • 已启用压缩

快速优化项

  1. 压缩:启用 gzip/brotli(体积减少 60-80%)
  2. 图像优化:使用 Next.js Image 组件
  3. 缓存:在 Redis 中缓存开销较大的操作
  4. 索引:为频繁查询的列添加索引
  5. 代码拆分:延迟加载大型组件
  6. 记忆化:对开销较大的操作使用 useMemo/useCallback

参考资料

评论

支持 Markdown