Skip to content
cccskills
FreePublished on GitHub

performance-optimization

优化前端性能 / 包大小 / 渲染 / 网络时使用。覆盖 Web Vitals (LCP/INP/CLS) / Bundle / Image / Code Splitting / 虚拟列表。融合性能预算 + RUM + 优化优先级。

The English summary is being prepared. Showing the original description.

See how to install

Files included (2)

  • SKILL.md12.8 KB
  • templates/performance-checklist.md3.9 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

性能优化(Performance Optimization)

参考来源:Google Web Vitals、Web.dev、Vercel Edge / Next.js 性能实践、Stripe 前端性能指南、Core Web Vitals 2024 更新(FID → INP)。

适用场景

  • 首屏速度优化(LCP / FCP)
  • 交互响应(INP / TTI)
  • 视觉稳定性(CLS)
  • 包大小优化
  • 大列表 / 大表格性能
  • 长任务拆解
  • 内存泄漏排查

核心原则

1. 测量优先,不要猜
   先 Lighthouse / DevTools / RUM
   定位瓶颈再优化

2. 性能预算
   首屏 JS < 200KB(gzip)
   首屏图片 < 200KB
   LCP < 2.5s / INP < 200ms / CLS < 0.1

3. 关注真实用户(RUM)
   实验室数据 ≠ 真实数据

4. 优先级:网络 → 渲染 → 计算
   - 减少传输
   - 减少阻塞
   - 减少重排

5. 不过早优化
   小项目过度优化 = 浪费时间

6. 持续监控
   性能退化是渐进的

Core Web Vitals 2026

指标含义好差
LCPLargest Contentful Paint< 2.5s> 4s
INPInteraction to Next Paint(替代 FID)< 200ms> 500ms
CLSCumulative Layout Shift< 0.1> 0.25
FCPFirst Contentful Paint< 1.8s> 3s
TTFBTime to First Byte< 800ms> 1.8s

性能预算(Performance Budget)

首屏(Critical Path):
  HTML:< 30 KB
  关键 CSS:< 15 KB(inline 或 critical CSS)
  JS(首屏):< 200 KB(gzip)
  字体:< 100 KB(仅必要字重)
  首屏图片:< 200 KB(webp/avif)
  
总页面:
  JS(全部):< 500 KB
  CSS(全部):< 100 KB
  图片(全部):< 1 MB

时间:
  TTFB:< 800ms
  LCP:< 2.5s
  INP:< 200ms
  CLS:< 0.1

测量工具

实验室

Lighthouse(Chrome DevTools / CLI):
  - Performance 评分
  - 4 个 Web Vitals
  - 问题清单

WebPageTest:
  - 多地理位置
  - 网络节流
  - 视频对比

Chrome DevTools:
  - Performance 面板(火焰图)
  - Network 面板
  - Coverage(未用代码)
  - Memory 面板(泄漏)

Bundle Analyzer:
  - webpack-bundle-analyzer
  - vite-bundle-visualizer
  - Source Map Explorer

真实用户(RUM)

import { onLCP, onINP, onCLS, onFCP, onTTFB } from 'web-vitals';

function sendToAnalytics(metric: any) {
  // 发到 Sentry / Datadog / GA / 自建
  navigator.sendBeacon('/analytics', JSON.stringify({
    name: metric.name,
    value: metric.value,
    id: metric.id,
    rating: metric.rating,  // 'good' | 'needs-improvement' | 'poor'
    url: window.location.pathname,
  }));
}

onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);
onFCP(sendToAnalytics);
onTTFB(sendToAnalytics);

1. 网络优化(最大杠杆)

减少 / 推迟资源

策略:
  □ 移除未用代码(Tree-shake)
  □ 第三方脚本 lazy load(async / defer)
  □ 字体子集 + font-display: swap
  □ 图片 webp / avif + responsive
  □ HTTP/2 / HTTP/3
  □ Brotli 压缩
  □ CDN 边缘

图片优化(最大坑)

// Next.js Image
<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  priority                    // 首屏加 priority
  placeholder="blur"
  blurDataURL="..."
/>

// 原生 picture
<picture>
  <source type="image/avif" srcset="hero.avif" />
  <source type="image/webp" srcset="hero.webp" />
  <img
    src="hero.jpg"
    alt="Hero"
    loading="lazy"            // 非首屏 lazy
    decoding="async"
    width="1200"
    height="600"              // 必填(防 CLS)
  />
</picture>

// Responsive srcset
<img
  src="hero-small.jpg"
  srcset="hero-small.jpg 400w, hero-medium.jpg 800w, hero-large.jpg 1200w"
  sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
  alt="Hero"
/>

字体优化

@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-var.woff2') format('woff2-variations');
  font-display: swap;          /* 不阻塞渲染 */
  font-weight: 100 900;
}

/* 子集 - 只用拉丁 */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/Inter-latin.woff2') format('woff2');
  unicode-range: U+0000-007F;
}
<!-- 关键字体预加载 -->
<link rel="preload" href="/fonts/Inter-var.woff2" as="font" type="font/woff2" crossorigin>

关键资源 preload / prefetch

<!-- 当前页关键 -->
<link rel="preload" href="/api/critical-data" as="fetch" crossorigin>

<!-- 下一页可能用 -->
<link rel="prefetch" href="/dashboard">

<!-- DNS 预解析 -->
<link rel="dns-prefetch" href="https://api.example.com">
<link rel="preconnect" href="https://api.example.com">

2. 包大小优化

Bundle 分析

# Vite
npm i -D rollup-plugin-visualizer
# vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer';
plugins: [visualizer({ open: true, gzipSize: true })]

# Webpack
npm i -D webpack-bundle-analyzer

Tree Shaking

// ✅ 命名导入(tree-shake 友好)
import { debounce } from 'lodash-es';

// ❌ 整库引入
import _ from 'lodash';

// ❌ CommonJS 难 tree-shake
import { debounce } from 'lodash';

Code Splitting

// 路由级(最重要)
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));

// 组件级(重组件 / 模态)
const HeavyChart = lazy(() => import('./HeavyChart'));

function App() {
  return (
    <Suspense fallback={<Skeleton />}>
      <HeavyChart />
    </Suspense>
  );
}

// 命名 chunk
const HeavyChart = lazy(() => 
  import(/* webpackChunkName: "heavy-chart" */ './HeavyChart')
);

替换大库

moment.js (66KB) → date-fns (modular) / dayjs (2KB)
lodash → lodash-es (tree-shake) / 单独函数
axios → fetch / ky
全 ECharts → echarts/core + 按需导入模块
全 lucide-react → lucide-react/icons/Specific

动态导入

// 按需加载重计算
async function exportToExcel(data) {
  const { utils, writeFile } = await import('xlsx');
  const ws = utils.json_to_sheet(data);
  // ...
}

3. 渲染优化

React 优化

// 1. memo(仅当父组件频繁渲染但 props 不变)
const ExpensiveItem = memo(function ExpensiveItem({ item }) {
  return <div>...</div>;
});

// 2. useMemo(重计算)
const filteredList = useMemo(
  () => list.filter(complexFilter),
  [list]
);

// 3. useCallback(传给 memo 子组件)
const handleClick = useCallback((id: number) => {
  setSelectedId(id);
}, []);

// 4. 状态拆分(减少重渲染范围)
// ❌ 大对象
const [state, setState] = useState({ ... 10 个字段 ... });

// ✅ 拆细
const [name, setName] = useState('');
const [age, setAge] = useState(0);
// ...

// 5. 用 Zustand selector 避免重渲染
const userName = useStore((s) => s.user.name);  // 仅 name 变才重渲

// 6. React Compiler(实验,自动优化)

Vue 3 优化

<!-- 1. v-once 静态内容 -->
<header v-once>
  <h1>{{ title }}</h1>
</header>

<!-- 2. v-memo 跳过重渲染 -->
<div v-for="item in list" v-memo="[item.id, item.selected]">
  ...
</div>

<!-- 3. 大列表 shallowRef -->
<script setup>
import { shallowRef } from 'vue';
const heavyData = shallowRef(largeArray);
</script>

<!-- 4. 异步组件 -->
<script setup>
import { defineAsyncComponent } from 'vue';
const HeavyChart = defineAsyncComponent(() => import('./HeavyChart.vue'));
</script>

虚拟列表(大数据必备)

// TanStack Virtual
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: 600, overflow: 'auto' }}>
      <div style={{ height: virtualizer.getTotalSize(), position: 'relative' }}>
        {virtualizer.getVirtualItems().map((virtualRow) => (
          <div
            key={virtualRow.key}
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              width: '100%',
              height: virtualRow.size,
              transform: `translateY(${virtualRow.start}px)`,
            }}
          >
            {items[virtualRow.index].name}
          </div>
        ))}
      </div>
    </div>
  );
}

CLS 优化

原因:图片 / 广告 / 字体 / 异步内容插入

解决:
  □ 图片必须有 width/height(保留位置)
  □ 字体 size-adjust 适配
  □ 骨架屏占位
  □ 广告 / 嵌入式预留容器(min-height)
  □ Skeleton 与最终尺寸一致
<!-- 必须 width / height -->
<img src="hero.jpg" alt="" width="1200" height="600" />

<!-- 或 aspect-ratio -->
<div style="aspect-ratio: 16/9; background: #eee;">
  <img src="hero.jpg" alt="" />
</div>

INP 优化

INP = 用户交互 → 下次绘制的时间

优化:
  □ 长任务拆分(< 50ms)
  □ 防抖输入
  □ 节流滚动
  □ Web Worker 计算
  □ requestIdleCallback / scheduler.yield()
  □ 避免 forced reflow
// 长任务拆分
async function processLargeData(data: Data[]) {
  const chunks = chunk(data, 100);
  for (const c of chunks) {
    processChunk(c);
    await new Promise(resolve => setTimeout(resolve, 0));  // yield
  }
}

// scheduler.yield()(新 API,更精确)
async function processLargeData(data: Data[]) {
  for (const item of data) {
    processItem(item);
    if ('scheduler' in window && 'yield' in scheduler) {
      await scheduler.yield();
    }
  }
}

// Web Worker
const worker = new Worker(new URL('./worker.ts', import.meta.url));
worker.postMessage(data);
worker.onmessage = (e) => setResult(e.data);

4. 缓存与离线

HTTP 缓存:
  - Cache-Control: public, max-age=31536000, immutable(哈希文件名)
  - ETag / Last-Modified(HTML)

Service Worker:
  - 预缓存关键资源
  - Stale-While-Revalidate
  - 离线兜底页

应用层:
  - TanStack Query 内存缓存
  - localStorage 用户偏好
  - IndexedDB 大量数据

5. SSR / 流式渲染

SSR 优势:
  - 首屏快(HTML 直出)
  - SEO 好
  
潜在问题:
  - TTFB 慢(服务端渲染要时间)
  - hydration 慢

优化:
  - Streaming SSR(HTML 流式返回)
  - Server Components(React 19)
  - Selective Hydration(部分 hydrate)
  - Islands(Astro / Qwik)
  - Resumability(Qwik)

性能优化优先级(ROI)

1. 图片优化(40% 收益)
2. 包大小(20%)
3. Code splitting(15%)
4. 虚拟列表(10%)
5. memo / useMemo(5%)
6. 微优化(5%)

不要:
  - 还没测就 memo 全部
  - useMemo 所有计算
  - useCallback 所有函数

工作流程

1. 测量基线
   - Lighthouse / RUM
   - 记录 Web Vitals

2. 找瓶颈
   - 网络(最常见)
   - 渲染(中等)
   - 计算(少)

3. 性能预算
   - 首屏 JS / CSS / 图片预算
   - LCP / INP / CLS 目标

4. 实施优化(按优先级)

5. 重新测量

6. 持续监控(RUM)

7. 性能退化告警
   - LCP P75 > 2.5s 持续 → 告警

配套模板

  • templates/performance-checklist.md — Web Vitals + 包大小 + 图片 + 字体 + 渲染 + 监控

质量自检

□ Lighthouse Performance ≥ 90
□ LCP < 2.5s(P75)
□ INP < 200ms(P75)
□ CLS < 0.1
□ 首屏 JS < 200KB(gzip)
□ 总 CSS < 100KB
□ 图片 webp/avif + 懒加载
□ 字体 woff2 + font-display: swap
□ 路由级 code splitting
□ 大列表虚拟化
□ Tree-shake 友好导入
□ 包分析检查
□ RUM 监控接入
□ 性能预算文档化

常见坑

  1. 图片不优化——LCP 直接挂
  2. 图片不限尺寸——CLS 爆炸
  3. 字体阻塞渲染——FOIT
  4. 整库引入——包翻倍
  5. 不 code splitting——首屏 1MB
  6. memo 全部——过度优化反而慢
  7. useEffect 滥用——无限重渲染
  8. 大列表不虚拟化——卡死
  9. 同步阻塞操作——长任务
  10. 不监控 RUM——线上才知道
  11. 第三方脚本同步加载——阻塞首屏
  12. CSS 大量 @import——串行加载
  13. 图片用 background-image——不能 lazy
  14. scroll handler 不节流——卡顿
  15. 不预加载关键字体——FOUT

与其他 skill 的协作

上游:
  ui-ux-designer 工作流 → 设计 / 图片资源
  api-designer → 接口性能 / 缓存策略

下游:
  build-deploy → 打包优化
  observability(前端)→ RUM 接入
  testing-frontend → 性能测试

相关参考

  • 项目根 references/frontend-tech-stack-guide.md — 性能工具

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

A/B 测试设计与分析时使用。适用于产品实验、功能验证、转化率优化。融合假设驱动 + 样本量计算 + 置信度判断。

The English summary is being prepared. Showing the original description.

zhaoxuya520/AI-Fullstack-Delivery-Workflow53Updated May 19, 2026

上线前业务方/产品方验收时使用。适用于功能交付确认、UAT、发布会签。融合 BDD Given-When-Then、Specification by Example、ATDD。

The English summary is being prepared. Showing the original description.

zhaoxuya520/AI-Fullstack-Delivery-Workflow53Updated May 19, 2026

设计无障碍可访问的界面时使用。适用于满足 WCAG 标准、键盘导航、屏幕阅读器支持。优先使用 WCAG 2.2 AA 级标准 + 键盘 + 焦点 + 对比度 + ARIA。

The English summary is being prepared. Showing the original description.

zhaoxuya520/AI-Fullstack-Delivery-Workflow53Updated May 19, 2026

实现可访问性(无障碍)时使用。覆盖 WCAG 2.2 AA / ARIA / 键盘导航 / 屏幕阅读器 / 颜色对比 / 焦点管理。融合 React Aria / Radix UI / Headless UI 实践 + axe-core 自动化测试。

The English summary is being prepared. Showing the original description.

zhaoxuya520/AI-Fullstack-Delivery-Workflow53Updated May 19, 2026

AI 模型部署时使用。适用于推理服务 / GPU / TensorRT / 监控 / 扩缩容。

The English summary is being prepared. Showing the original description.

zhaoxuya520/AI-Fullstack-Delivery-Workflow53Updated May 19, 2026

数据分析报告输出时使用。适用于业务分析报告、周报、专项分析、决策支持。融合洞察 + 建议 + 行动项。

The English summary is being prepared. Showing the original description.

zhaoxuya520/AI-Fullstack-Delivery-Workflow53Updated May 19, 2026

See all skills by zhaoxuya520

Report a problem with this skill