From 1a6b476c3f5013a32678820c1781827123af2445 Mon Sep 17 00:00:00 2001 From: Chris Hondl Date: Thu, 9 Jul 2026 23:46:25 -0700 Subject: [PATCH 1/3] Reduce not-found render delay from 8s to 1.5s The not-found placeholder waited 8000ms before rendering, leaving a blank content area for 8 full seconds on any nonexistent or slow-to-load entity (/team/99999, /event/2026zzzzz, etc.). The debounce exists only to avoid a flash of the not-found message before data arrives; 1.5s is ample for that while no longer looking like a hung page. (The comment already described the intent as 'one second'; the 8000 value grew from 1000 over prior commits.) --- frontend/src/pagesContent/shared/notFound.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pagesContent/shared/notFound.tsx b/frontend/src/pagesContent/shared/notFound.tsx index 0f03fa67..269bd50f 100644 --- a/frontend/src/pagesContent/shared/notFound.tsx +++ b/frontend/src/pagesContent/shared/notFound.tsx @@ -11,7 +11,7 @@ const NotFound = ({ type }: { type: string }) => { useEffect(() => { setTimeout(() => { setRender(true); - }, 8000); + }, 1500); }, []); if (!render) { From f68ed7364c0634a2196cbc4d4a403705ef2c7840 Mon Sep 17 00:00:00 2001 From: Chris Hondl Date: Thu, 9 Jul 2026 23:46:25 -0700 Subject: [PATCH 2/3] Dedup in-flight fetches in storage query() On team pages multiple components concurrently request the same event/blob resources. Each caller awaits getWithExpiry(), all miss IndexedDB (nothing is written until a fetch completes), and all issue their own network fetch, so every blob/API resource was downloaded twice per page load. Add a module-level in-flight promise map keyed by storageKey: concurrent callers for the same key now share one fetch, and the entry is cleared once it settles. --- frontend/src/api/storage.tsx | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/frontend/src/api/storage.tsx b/frontend/src/api/storage.tsx index d5b17b19..f7db1ebe 100644 --- a/frontend/src/api/storage.tsx +++ b/frontend/src/api/storage.tsx @@ -37,19 +37,14 @@ export function decompress(buffer: any) { return data; } -async function query( +const inFlight: { [storageKey: string]: Promise } = {}; + +async function fetchAndStore( storageKey: string, apiPath: string, checkBucket: boolean, - minLength: number, expiry: number ) { - const cacheData = await getWithExpiry(storageKey); - if (cacheData && (minLength === 0 || cacheData?.length > minLength)) { - log(`Used Local Storage: ${storageKey}`); - return cacheData; - } - const start = performance.now(); let buffer = null; @@ -85,4 +80,26 @@ async function query( } } +async function query( + storageKey: string, + apiPath: string, + checkBucket: boolean, + minLength: number, + expiry: number +) { + const cacheData = await getWithExpiry(storageKey); + if (cacheData && (minLength === 0 || cacheData?.length > minLength)) { + log(`Used Local Storage: ${storageKey}`); + return cacheData; + } + + if (!inFlight[storageKey]) { + inFlight[storageKey] = fetchAndStore(storageKey, apiPath, checkBucket, expiry).finally(() => { + delete inFlight[storageKey]; + }); + } + + return inFlight[storageKey]; +} + export default query; From bdee5e767be2cf6461e9d61b52af873b89eac8cb Mon Sep 17 00:00:00 2001 From: Chris Hondl Date: Thu, 9 Jul 2026 23:46:25 -0700 Subject: [PATCH 3/3] Sort null-score matches last in noteworthy queries CockroachDB orders NULLs first under ORDER BY ... DESC, so a match whose clean score is null on both alliances (a fully-DQed / placeholder match, e.g. 2026txmca_sf6m1) sorted to the top of every noteworthy list -- ranking a 0/null result as the highest clean score. greatest()/sum() over the no_foul columns yields null when both alliances lack a clean result. Add .nullslast() to every noteworthy order_by so these matches fall to the bottom (out of the top 30) and real high-scoring matches rank first, while legitimate single-DQ matches keep ranking by their scoring alliance. --- backend/src/db/functions/noteworthy_matches.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/src/db/functions/noteworthy_matches.py b/backend/src/db/functions/noteworthy_matches.py index 889b238a..017f22fe 100644 --- a/backend/src/db/functions/noteworthy_matches.py +++ b/backend/src/db/functions/noteworthy_matches.py @@ -55,14 +55,14 @@ def callback(session: SessionType): matches.add_columns( func.greatest(red_score_col, blue_score_col).label("max_score") ) - .order_by(desc("max_score"), asc(MatchORM.time)) # type: ignore + .order_by(desc("max_score").nullslast(), asc(MatchORM.time)) # type: ignore .limit(30) .all() ) combined_score_matches = ( matches.add_columns((red_score_col + blue_score_col).label("sum_score")) # type: ignore - .order_by(desc("sum_score"), asc(MatchORM.time)) # type: ignore + .order_by(desc("sum_score").nullslast(), asc(MatchORM.time)) # type: ignore .limit(30) .all() ) @@ -73,7 +73,7 @@ def callback(session: SessionType): "losing_score" ), ) - .order_by(desc("losing_score"), asc(MatchORM.time)) # type: ignore + .order_by(desc("losing_score").nullslast(), asc(MatchORM.time)) # type: ignore .limit(30) .all() ) @@ -86,7 +86,7 @@ def callback(session: SessionType): "max_auto_score" ) ) - .order_by(desc("max_auto_score"), asc("time")) # type: ignore + .order_by(desc("max_auto_score").nullslast(), asc("time")) # type: ignore .limit(30) .all() ) @@ -97,7 +97,7 @@ def callback(session: SessionType): "max_teleop_score" ) ) - .order_by(desc("max_teleop_score"), asc("time")) # type: ignore + .order_by(desc("max_teleop_score").nullslast(), asc("time")) # type: ignore .limit(30) .all() ) @@ -108,7 +108,7 @@ def callback(session: SessionType): "max_endgame_score" ) ) - .order_by(desc("max_endgame_score"), asc("time")) # type: ignore + .order_by(desc("max_endgame_score").nullslast(), asc("time")) # type: ignore .limit(30) .all() )