Perf updates - #79
Merged
Merged
Conversation
The map page built and server-rendered all 11 tab contents on every load, so each heavy tab (heatmap, replay, routes, events, compare, killfeed, charts, overview) ran its own queries even when the user never opened it. Render only the tab selected via ?tab= and stream it under Suspense; switching tabs is now a shallow:false navigation. Fight-initiation is computed only when its tab is open.
ScrimPagination fired a second get-scrims request (limit=1, no filters) on every load and team switch purely to tell an empty account apart from empty filter results. The API now returns hasAnyScrims on the main response, computed with a cheap findFirst only when the filtered page is empty, so the client needs a single request instead of two.
The scrim overview page ran ~12 reads as a sequential await chain even though most don't depend on each other. Group them into three parallel tiers: the scrim/maps/user/feedback/visibility/flag reads, then the permission and context reads that need the scrim and user, then the four heavy overview/positional/ initiation reads that were previously awaited one after another. Behavior is unchanged; an early integer guard keeps malformed ids returning notFound before the batch runs.
The overview ran its ten panel services with concurrency:"unbounded". The shared base read is already deduped by an Effect cache, so firing everything at once mostly just lets the secondary per-panel queries spike the connection pool and stretch the tail past the 60s budget. Cap concurrency at 4.
The overview awaited all ten panel reads before sending any HTML, so the page's first byte waited on the slowest service. Split it into three Suspense sections — quick-stats ribbon, the insights + map-performance analysis block, and the roster — each fetching only its own slice. The shared per-team base read is deduped by the existing Effect cache, so the above-the-fold ribbon paints while the heavier blocks stream in. Skeleton fragments are extracted so the route loading boundary and the per-section fallbacks share them.
The hero stat-card percentile queries scan the whole PlayerStat table per hero and were the app's biggest rows-read offender (~38M rows/day) despite being global, slowly-changing population statistics. Wrap the two actively-used baseline functions in unstable_cache with a 6h TTL so repeated stat-card reads collapse to one scan per (hero, params) window. A shared hero-baselines tag is attached so an upload hook can bust them eagerly later via revalidateTag.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.