用途
React Router Loader Performance 是一套面向 React Router v7 loader 的关键性能优化技巧集合,包含 4 条规则,重点在于消除瀑布流(waterfall)并最大化并行执行。资料将其影响级别标为 CRITICAL,理由是 loader 性能直接影响首字节时间(TTFB)和用户感知的页面速度。
适用时机包括:
- Loader TTFB 超过 500ms
- 多个数据库查询按顺序执行
- 次要数据(推荐、分析)阻塞关键路径
- 数据库延迟较高(单次查询 >50ms)
- 优化 React Router v7 数据加载模式
主要能力(规则摘要)
1. 数据库优化(CRITICAL)
规则:loader-consolidate-queries(见 @rules/loader-consolidate-queries.md)。
使用 ORM 的 includes/relations 将多次数据获取合并为单次查询。
资料示例(代码保持原样):
// Bad: 3 DB calls (~450ms on 150ms latency)
const product = await db.product.findUnique({ where: { id } });
const reviews = await db.review.findMany({ where: { productId: id } });
const variations = await db.variation.findMany({ where: { productId: id } });
// Good: 1 DB call (~200ms)
const product = await db.product.findUnique({
where: { id },
include: { reviews: true, variations: true },
});
资料说明该规则通常是 loader 性能提升最大的一项,在高延迟数据库连接上尤其明显。
2. 流式优化(HIGH)
规则:loader-defer-slow-secondary(见 @rules/loader-defer-slow-secondary.md)。
对非关键数据不进行 await,直接流式传输。
资料示例(代码保持原样):
// Bad: blocks on slow operation (~3500ms TTFB)
const product = await getProduct(id); // 500ms
const recommendations = await getRecommendations(product); // 3000ms
return data({ product, recommendations }); // TTFB: 3500ms
// Good: streams secondary data (~500ms TTFB)
const product = await getProduct(id); // 500ms
const recommendations = getRecommendations(product); // Don't await
return data({ product, recommendations }); // TTFB: 500ms
资料说明该做法的价值在于让慢操作离开关键路径:用户查看商品时,推荐数据同时在流式传输。
3. 基础设施优化(HIGH)
规则:infrastructure-colocation。
尽量减少服务器与数据库之间的地理距离。
资料给出的关键指标:
- 同区域:延迟 <10ms
- 跨区域:延迟 50-200ms
- 跨洲:延迟 >100ms
建议动作:
- 将数据库与服务器托管在同一云区域
- 对读密集路由,在应用服务器附近使用只读副本
- 分析 ORM 查询日志,找出持续 >30ms 的延迟
资料指出,当数据库延迟较高时,基础设施变更带来的收益大于代码优化。
4. 并行执行(CRITICAL)
规则:promise-all-independent(资料注明该内容涵盖于 frontend-async-best-practices)。
对相互独立的异步操作使用 Promise.all。
资料示例(代码保持原样):
// Bad: sequential (~900ms)
const product = await fetchProduct(); // 400ms
const reviews = await fetchReviews(); // 300ms
const variations = await fetchVariations(); // 200ms
// Good: parallel (~400ms)
const [product, reviews, variations] = await Promise.all([
fetchProduct(),
fetchReviews(),
fetchVariations(),
]);
资料说明其效果:总耗时等于最慢的操作,而不是所有操作之和。
使用方式
性能目标
- TTFB:关键路径 <500ms
- 数据库延迟:单次查询 <30ms(用 ORM 日志测量)
- 次要数据:任何非关键且 >1000ms 的内容都进行流式传输
测量
资料建议使用 Server-Timing 请求头定位瓶颈,示例代码如下(保持原样):
import { time } from "~/utils/timing.server";
export async function loader({ params }: Route.LoaderArgs) {
const product = await time("product", () => getProduct(params.id));
const recommendations = time("recommendations", () =>
getRecommendations(product)
);
return data({ product, recommendations });
}
然后在 Chrome DevTools 的 Network 面板中查看 Server-Timing 明细。
适用场景
- React Router v7 项目的 loader 性能调优
- 排查 TTFB 偏高、数据库查询串行执行的问题
- 需要将推荐、分析等次要数据移出关键路径的页面
- 数据库与应用服务器跨区域部署、延迟较高的架构
限制
资料未说明该技能的具体安装命令、支持的运行环境版本、授权或收费方式,这些信息暂未提供。规则中引用的 @rules/ 文件与 frontend-async-best-practices 属于该技能集内的引用,资料未提供其完整内容。