Compare commits

...
Author SHA1 Message Date
Thomas 9239e6ecc5 Merge branch 'dev' into perf/parallelize-board-prefetch 2026-05-27 09:38:16 +02:00
Thomas 8bb284e1d3 Delete apps/nextjs/src/app/[locale]/boards/(content)/_creator.spec.ts 2026-05-25 09:42:38 +02:00
Thomas Camlong 52fc678e44 test(boards): add tests for parallelized board page data fetching 2026-05-22 09:00:02 +02:00
Thomas Camlong 136c269935 perf(boards): parallelize board page data fetching
Board fetch + auth() now run concurrently via Promise.all instead of
sequentially. Widget prefetches for all kinds also run in parallel
alongside integration permission loading.
2026-05-21 14:01:01 +02:00
@@ -41,13 +41,11 @@ export const createBoardContentPage = <TParams extends Record<string, unknown>>(
}), }),
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
page: async ({ params }: { params: Promise<TParams> }) => { page: async ({ params }: { params: Promise<TParams> }) => {
const session = await auth(); const resolvedParams = await params;
const integrations = await getIntegrationsWithPermissionsAsync(session);
const board = await getInitialBoard(await params);
const queryClient = getQueryClient(); const queryClient = getQueryClient();
// Prefetch item data const [board, session] = await Promise.all([getInitialBoard(resolvedParams), auth()]);
const itemsMap = board.items.reduce((acc, item) => { const itemsMap = board.items.reduce((acc, item) => {
const existing = acc.get(item.kind); const existing = acc.get(item.kind);
if (existing) { if (existing) {
@@ -58,8 +56,10 @@ export const createBoardContentPage = <TParams extends Record<string, unknown>>(
return acc; return acc;
}, new Map<WidgetKind, Item[]>()); }, new Map<WidgetKind, Item[]>());
for (const [kind, items] of itemsMap) { const [integrations] = await Promise.all([
await prefetchForKindAsync(kind, queryClient, items).catch((error) => { getIntegrationsWithPermissionsAsync(session),
...Array.from(itemsMap).map(([kind, items]) =>
prefetchForKindAsync(kind, queryClient, items).catch((error) => {
logger.error( logger.error(
new ErrorWithMetadata( new ErrorWithMetadata(
"Failed to prefetch widget", "Failed to prefetch widget",
@@ -67,8 +67,9 @@ export const createBoardContentPage = <TParams extends Record<string, unknown>>(
{ cause: error }, { cause: error },
), ),
); );
}); }),
} ),
]);
return ( return (
<HydrationBoundary state={dehydrate(queryClient)}> <HydrationBoundary state={dehydrate(queryClient)}>