关于 frontend-excellence
frontend-excellence 是面向 React 和 Next.js 开发者的前端参考技能,涵盖渲染、加载、包体积、图像、布局稳定性和性能测量。
主要功能
- 01React Server Components 与流式 SSR
- 02代码拆分与包优化
- 03Core Web Vitals 指标与调优
- 04图像和字体加载建议
- 05防止 CLS 的方法
- 06真实用户性能测量
适用场景
- 01设计服务端与客户端组件边界
- 02缩减 JavaScript 包体积
- 03改善图像加载和布局稳定性
- 04监测 LCP、INP 和 CLS
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ rohitg00/ awesome-claude-code-toolkit --skill frontend-excellence安装后在 Claude Code 中输入/frontend-excellence确认已加载。
详细介绍
前端卓越实践
React Server Components
Server Components 在服务器上运行,并将渲染后的 HTML 发送给客户端。它们可以直接访问数据库、文件系统和内部 API,而不会将这些内容暴露给浏览器。
// app/products/page.tsx (Server Component by default)
async function ProductsPage() {
const products = await db.query("SELECT * FROM products WHERE active = true");
return (
<main>
<h1>Products</h1>
<ProductList products={products} />
<AddToCartButton /> {/* Client Component */}
</main>
);
}
规则:
- Server Components 不能使用
useState、useEffect或浏览器 API - 在文件顶部使用
'use client'标记交互式组件 - 将可序列化的属性从 Server Components 传递给 Client Components(不能传递函数或类)
- 尽可能将
'use client'边界放在组件树的深处
流式 SSR
import { Suspense } from 'react';
export default function Dashboard() {
return (
<div>
<Header /> {/* renders immediately */}
<Suspense fallback={<ChartSkeleton />}>
<AnalyticsChart /> {/* streams when ready */}
</Suspense>
<Suspense fallback={<TableSkeleton />}>
<RecentOrders /> {/* streams independently */}
</Suspense>
</div>
);
}
每个 Suspense 边界都会独立流式传输。请在数据获取组件周围设置边界,避免整个页面被阻塞。
代码拆分
import dynamic from 'next/dynamic';
const HeavyEditor = dynamic(() => import('@/components/Editor'), {
loading: () => <EditorSkeleton />,
ssr: false,
});
const AdminPanel = dynamic(() => import('@/components/AdminPanel'));
拆分位置:
- 路由边界(在 Next.js App Router 中自动拆分)
- 条件渲染的组件(模态框、抽屉、管理面板)
- 大型库(图表库、富文本编辑器、地图)
- 首屏以下的内容
Bundle 优化
// next.config.js
module.exports = {
experimental: {
optimizePackageImports: ['lucide-react', '@heroicons/react', 'lodash-es'],
},
};
检查清单:
- 运行
npx next build并检查各路由的输出大小 - 使用
@next/bundle-analyzer查找大型依赖项 - 用
date-fns或dayjs替换moment(可节省约 200KB) - 导入特定函数:
import { debounce } from 'lodash-es/debounce' - 动画优先使用 CSS 而非 JS(无需运行时开销)
- 对图标库进行摇树优化:
import { Search } from 'lucide-react'
Core Web Vitals 目标
| 指标 | 良好 | 需要改进 | 较差 |
|---|---|---|---|
| LCP(最大内容绘制) | <2.5s | 2.5-4.0s | >4.0s |
| INP(下一次绘制交互延迟) | <200ms | 200-500ms | >500ms |
| CLS(累积布局偏移) | <0.1 | 0.1-0.25 | >0.25 |
LCP 优化
- 预加载主视觉图片:
<link rel="preload" as="image" href="..." /> - 对首屏
<Image>组件使用priority属性 - 内联关键 CSS,延迟加载非关键样式表
- 避免对首屏内容进行客户端渲染
- 为图片设置明确的
width/height,防止布局偏移
图片优化
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="Descriptive alt text"
width={1200}
height={630}
priority // preload for LCP images
sizes="(max-width: 768px) 100vw, 50vw"
placeholder="blur"
blurDataURL={base64} // inline tiny placeholder
/>
- 使用
next/image或同类方案(自动生成 WebP/AVIF,提供响应式 srcset) - 设置
sizes属性,避免下载尺寸过大的图片 - 使用带有 base64 数据 URL 的
placeholder="blur",提升感知性能 - 延迟加载首屏以下的图片(默认行为)
字体加载策略
// app/layout.tsx
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap', // show fallback font immediately
preload: true,
variable: '--font-inter',
});
export default function RootLayout({ children }) {
return (
<html className={inter.variable}>
<body>{children}</body>
</html>
);
}
- 使用
next/font实现不会导致 CLS 的字体加载,并自动进行子集化 - 设置
display: 'swap',避免加载期间文本不可见 - 使用自托管字体,而非从 Google CDN 加载(可节省 DNS 查询)
- 最多使用 2 种字体系列
防止 CLS
- 始终为图片和视频设置
width和height - 使用
aspect-ratioCSS 为响应式媒体容器设置纵横比 - 使用
min-height为动态内容(广告、嵌入内容)预留空间 - 避免在加载完成后于现有内容上方插入内容
- 对尺寸会变化的组件使用 CSS
contain: layout
性能监控
import { onCLS, onINP, onLCP } from 'web-vitals';
onCLS(console.log);
onINP(console.log);
onLCP(console.log);
衡量真实用户指标(RUM),而不仅仅是实验室评分。Vercel Analytics 和 Google Search Console 可提供现场数据。
评论
支持 Markdown