dify/web/app/components/plugins/marketplace/server-budget.ts
Coding On Star cb6c04637b
feat(web): add marketplace creator profiles and homepage redesign (#41538)
Co-authored-by: zxhlyh <jasonapring2015@outlook.com>
Co-authored-by: fatelei <fatelei@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: 姜涵煦 <hanxujiang@jianghanxudeMacBook-Pro-2.local>
Co-authored-by: L1nSn0w <l1nsn0w@qq.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-04 08:09:45 +00:00

37 lines
1.4 KiB
TypeScript

/**
* How long a server render may wait for Marketplace data before giving up on
* server-side rendering it.
*
* The catalog routes prefetch on the server so results land in the initial HTML
* (crawlers, first paint). Awaiting that prefetch to completion makes the whole
* RSC response hostage to the Marketplace API: with a slow upstream the browser
* sits on the *previous* page with no feedback, which is what "search just spins
* forever" looks like from the outside. Measured against a 3s-delayed API, an
* unbounded await pushed time-to-first-byte to ~7s.
*
* Nothing is lost when the budget expires: the client re-requests whatever is
* missing from the dehydrated state, and TanStack Query is configured to
* dehydrate still-pending queries, so in-flight work streams instead of
* blocking. Server rendering degrades exactly when it is too slow to be worth
* waiting for.
*
* Homepage (`variant="home"`) overlaps banners and catalog prefetch under one
* budget so a slow banner cannot add a second 2.5s onto the catalog wait.
*/
export const SERVER_PREFETCH_BUDGET_MS = 2_500
export async function withinServerBudget(work: Promise<unknown>): Promise<void> {
let cancelBudget = () => {}
try {
await Promise.race([
work,
new Promise<void>((resolve) => {
const timer = setTimeout(resolve, SERVER_PREFETCH_BUDGET_MS)
cancelBudget = () => clearTimeout(timer)
}),
])
} finally {
cancelBudget()
}
}