frontend-async-best-practices by sergiodxa/agent-skills
npx skills add https://github.com/sergiodxa/agent-skills --skill frontend-async-best-practices适用于异步 JavaScript 代码的性能优化模式。包含 5 条规则,专注于消除请求瀑布流并最大化并行性。
影响:关键 - 瀑布流是头号性能杀手。每个顺序的 await 都会增加完整的网络延迟。
在以下情况下参考这些指南:
对独立操作使用 Promise.all()。
// 错误:3 次顺序往返
const user = await fetchUser();
const posts = await fetchPosts();
const comments = await fetchComments();
// 正确:1 次并行往返
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments(),
]);
将 await 移动到实际使用的分支中。
// 错误:即使跳过也总是等待
async function handle(skip: boolean) {
let data = await fetchData();
if (skip) return { skipped: true };
return process(data);
}
// 正确:仅在需要时等待
async function handle(skip: boolean) {
if (skip) return { skipped: true };
let data = await fetchData();
return process(data);
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
链式处理依赖操作,并行化独立操作。
// 错误:profile 不必要地等待 config
const [user, config] = await Promise.all([fetchUser(), fetchConfig()]);
const profile = await fetchProfile(user.id);
// 正确:profile 在 user 解析后立即开始
const userPromise = fetchUser();
const profilePromise = userPromise.then((user) => fetchProfile(user.id));
const [user, config, profile] = await Promise.all([
userPromise,
fetchConfig(),
profilePromise,
]);
在加载器中尽早启动 Promise,稍后再等待。
// 错误:顺序执行
export async function loader() {
let session = await auth();
let config = await fetchConfig();
return { session, config };
}
// 正确:并行执行
export async function loader() {
let sessionPromise = auth();
let configPromise = fetchConfig();
const [session, config] = await Promise.all([sessionPromise, configPromise]);
return { session, config };
}
使用 Suspense 在数据加载时立即显示 UI。
// 错误:整个页面被数据阻塞
async function Page() {
let data = await fetchData();
return (
<Layout>
<Content data={data} />
</Layout>
);
}
// 正确:布局立即显示,内容流式加载
function Page() {
return (
<Layout>
<Suspense fallback={<Skeleton />}>
<Content />
</Suspense>
</Layout>
);
}
每周安装量
93
代码仓库
GitHub 星标数
81
首次出现
2026 年 1 月 28 日
安全审计
安装于
codex73
opencode73
github-copilot72
gemini-cli67
kimi-cli60
amp59
Performance optimization patterns for asynchronous JavaScript code. Contains 5 rules focused on eliminating request waterfalls and maximizing parallelism.
Impact: CRITICAL - Waterfalls are the #1 performance killer. Each sequential await adds full network latency.
Reference these guidelines when:
Use Promise.all() for independent operations.
// 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(),
]);
Move await into branches where actually used.
// 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);
}
Chain dependent operations, parallelize independent ones.
// 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,
]);
Start promises early, await late in loaders.
// 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 };
}
Use Suspense to show UI immediately while data loads.
// 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>
);
}
Weekly Installs
93
Repository
GitHub Stars
81
First Seen
Jan 28, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex73
opencode73
github-copilot72
gemini-cli67
kimi-cli60
amp59
ESLint迁移到Oxlint完整指南:JavaScript/TypeScript项目性能优化工具
1,700 周安装