mcpField
P
performance-optimization

performance-optimization

github.com/rohitg00开发2.8k188 次安装25 周前更新
代码仓库

关于 performance-optimization

面向 Web 应用开发者的前端性能参考,汇集 Bundle 分析、代码拆分、图像优化、Core Web Vitals 监控和实施检查项。

主要功能

  1. 01Bundle 分析与代码拆分
  2. 02图像优化实践
  3. 03Core Web Vitals 监控
  4. 04缓存与资源交付检查
  5. 05性能反模式清单

适用场景

  1. 01减少初始 JavaScript 加载量
  2. 02改善图像交付与布局稳定性
  3. 03监控 LCP、INP 和 CLS

安装

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

$npx skills add https://github.com/rohitg00/awesome-claude-code-toolkit --skill performance-optimization

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

详细介绍

性能优化

包分析与代码拆分

// Dynamic import for route-level code splitting
const Dashboard = lazy(() => import("./pages/Dashboard"));
const Settings = lazy(() => import("./pages/Settings"));

function App() {
  return (
    <Suspense fallback={<PageSkeleton />}>
      <Routes>
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/settings" element={<Settings />} />
      </Routes>
    </Suspense>
  );
}
// vite.config.ts - manual chunk splitting
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ["react", "react-dom"],
          charts: ["recharts", "d3"],
          editor: ["@monaco-editor/react"],
        },
      },
    },
  },
});
# Analyze bundle composition
npx vite-bundle-visualizer
npx source-map-explorer dist/assets/*.js

图像优化

import Image from "next/image";

function ProductImage({ src, alt }: { src: string; alt: string }) {
  return (
    <Image
      src={src}
      alt={alt}
      width={800}
      height={600}
      sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
      placeholder="blur"
      blurDataURL={generateBlurHash(src)}
      loading="lazy"
    />
  );
}

<img
  src="product.webp"
  alt="Product photo"
  width="800"
  height="600"
  loading="lazy"
  decoding="async"
  fetchpriority="low"
/>


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

缓存标头

function setCacheHeaders(res: Response, options: CacheOptions) {
  if (options.immutable) {
    res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
    return;
  }

  if (options.revalidate) {
    res.setHeader("Cache-Control", `public, max-age=0, s-maxage=${options.revalidate}, stale-while-revalidate=${options.staleWhileRevalidate ?? 86400}`);
    return;
  }

  res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
}

app.use("/assets", (req, res, next) => {
  setCacheHeaders(res, { immutable: true });
  next();
});

app.use("/api", (req, res, next) => {
  setCacheHeaders(res, { revalidate: 60, staleWhileRevalidate: 3600 });
  next();
});

大型数据的虚拟列表

import { useVirtualizer } from "@tanstack/react-virtual";

function VirtualList({ items }: { items: Item[] }) {
  const parentRef = useRef<HTMLDivElement>(null);

  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 50,
    overscan: 5,
  });

  return (
    <div ref={parentRef} style={{ height: "600px", overflow: "auto" }}>
      <div style={{ height: `${virtualizer.getTotalSize()}px`, position: "relative" }}>
        {virtualizer.getVirtualItems().map((virtualRow) => (
          <div
            key={virtualRow.key}
            style={{
              position: "absolute",
              top: 0,
              transform: `translateY(${virtualRow.start}px)`,
              height: `${virtualRow.size}px`,
              width: "100%",
            }}
          >
            <ItemRow item={items[virtualRow.index]} />
          </div>
        ))}
      </div>
    </div>
  );
}

Core Web Vitals 监控

import { onCLS, onINP, onLCP } from "web-vitals";

function sendMetric(metric: { name: string; value: number; id: string }) {
  navigator.sendBeacon("/api/vitals", JSON.stringify(metric));
}

onCLS(sendMetric);
onINP(sendMetric);
onLCP(sendMetric);
  • LCP(最大内容绘制):< 2.5s。预加载主视觉图像,优化服务器响应时间。
  • INP(下一次绘制交互):< 200ms。避免长任务,使用 requestIdleCallback。
  • CLS(累积布局偏移):< 0.1。为图像和嵌入内容设置明确的尺寸。

反模式

  • 一次性加载所有 JavaScript,而不是按路由拆分代码
  • 提供未经优化的图像(不使用 WebP/AVIF,也不设置响应式尺寸)
  • 图像缺少 width 和 height(会导致布局偏移)
  • 对带内容哈希的静态资源使用 Cache-Control: no-cache
  • 渲染数千个 DOM 节点,而不是对列表进行虚拟化
  • 使用同步计算阻塞主线程

检查清单

  • 路由使用动态 import() 和 Suspense 懒加载
  • 已分析包,并拆分出供应商代码块
  • 图像以 WebP/AVIF 格式提供,并带有响应式 sizes 属性
  • 使用 fetchpriority="high" 预加载 LCP 图像
  • 静态资源使用不可变标头和内容哈希进行缓存
  • 包含 100 项以上的列表使用虚拟化
  • 在生产环境中监控 Core Web Vitals(LCP、INP、CLS)
  • 关键路径上没有阻塞渲染的资源

评论

支持 Markdown