关于 frontend-async-best-practices
面向编写数据获取代码的开发者,提供 JavaScript 异步性能实践,包含减少请求瀑布并提升并行度的五条规则。
主要功能
- 01用 Promise.all() 并行执行独立操作
- 02推迟 await,直到需要结果时
- 03高效串联存在依赖的操作
- 04在 API 路由中尽早启动 Promise
- 05使用 Suspense 在数据加载时渲染界面
适用场景
- 01检查异步代码中的串行请求瀑布
- 02优化 Remix loaders 和 actions 的数据获取
- 03改善多个异步操作的响应时间
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ sergiodxa/ agent-skills --skill frontend-async-best-practices安装后在 Claude Code 中输入/frontend-async-best-practices确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
rules/api-routes.mddefer-await.mddependencies.mdparallel.mdsuspense-boundaries.md详细介绍
异步最佳实践
异步 JavaScript 代码的性能优化模式。包含 5 条规则,重点在于消除请求瀑布流并最大限度地提高并行度。
影响:严重 —— 瀑布流是性能问题的头号杀手。每个顺序执行的 await 都会增加完整的网络延迟。
适用场景
在以下情况下参考这些指南:
- 编写 Remix 加载器或操作
- 实现数据获取逻辑
- 处理多个异步操作
- 检查代码中的瀑布流模式
- 优化响应时间
规则摘要
parallel(严重)—— @rules/parallel.md
对彼此独立的操作使用 Promise.all()。
// Bad: 3 sequential round trips
const user = await fetchUser();
const posts = await fetchPosts();
const comments = await fetchComments();
// Good: 1 parallel round trip
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments(),
]);
defer-await(高)—— @rules/defer-await.md
将 await 移至实际使用它的分支中。
// Bad: always waits even when skipping
async function handle(skip: boolean) {
let data = await fetchData();
if (skip) return { skipped: true };
return process(data);
}
// Good: only waits when needed
async function handle(skip: boolean) {
if (skip) return { skipped: true };
let data = await fetchData();
return process(data);
}
dependencies(严重)—— @rules/dependencies.md
串联有依赖关系的操作,并行执行彼此独立的操作。
// Bad: profile waits for config unnecessarily
const [user, config] = await Promise.all([fetchUser(), fetchConfig()]);
const profile = await fetchProfile(user.id);
// Good: profile starts as soon as user resolves
const userPromise = fetchUser();
const profilePromise = userPromise.then((user) => fetchProfile(user.id));
const [user, config, profile] = await Promise.all([
userPromise,
fetchConfig(),
profilePromise,
]);
api-routes(严重)—— @rules/api-routes.md
在加载器中尽早启动 Promise,延后等待结果。
// Bad: sequential execution
export async function loader() {
let session = await auth();
let config = await fetchConfig();
return { session, config };
}
// Good: parallel execution
export async function loader() {
let sessionPromise = auth();
let configPromise = fetchConfig();
const [session, config] = await Promise.all([sessionPromise, configPromise]);
return { session, config };
}
suspense-boundaries(高)—— @rules/suspense-boundaries.md
使用 Suspense,在数据加载期间立即显示 UI。
// Bad: entire page blocked by data
async function Page() {
let data = await fetchData();
return (
<Layout>
<Content data={data} />
</Layout>
);
}
// Good: layout shows immediately, content streams in
function Page() {
return (
<Layout>
<Suspense fallback={<Skeleton />}>
<Content />
</Suspense>
</Layout>
);
}
评论
支持 Markdown