From 42039372efc51a8bc020ac597b2dd83028427f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 17 May 2026 13:01:19 +0200 Subject: [PATCH] fix(insights): remove inert Suspense wrappers from mother page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The v1.4.36 perf wave wrapped the briefing / correlation / trends blocks in `` boundaries. The page is `"use client"`, the blocks load via `next/dynamic({ ssr: false })` (no promise throw on hydrate), and TanStack Query hooks never throw thenables, so the boundaries never engaged — dead code, masking the real shape of the delivery. The actual perceptual win remains intact: the page-level `isLoading` gate is gone, the hero plus each section's own loader skeleton paints inside the first paint budget while data fills in. A comment in the file explains why no `` wrapper belongs here so a future contributor doesn't re-add one. NOTE for CHANGELOG drafting: the perf-wave bullet should read "early-skeleton paint" rather than "Suspense streaming". Genuinely streamed server children remain a v1.5.x track. --- src/app/insights/page.tsx | 56 +++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/src/app/insights/page.tsx b/src/app/insights/page.tsx index f19ffd9c2..6da28b302 100644 --- a/src/app/insights/page.tsx +++ b/src/app/insights/page.tsx @@ -1,6 +1,5 @@ "use client"; -import { Suspense } from "react"; import { useQuery } from "@tanstack/react-query"; import dynamic from "next/dynamic"; import Link from "next/link"; @@ -219,19 +218,18 @@ export default function InsightsPage() { const briefingPayload = advisor.payload?.dailyBriefing ?? null; const heroStripUpdatedAt = advisor.payload?.cachedAt ?? null; - // Skeleton fallbacks for each Suspense boundary. Match the loaded- - // chunk height so the layout doesn't shift when the lazy import - // resolves. The TrendsRow skeleton mirrors the chart-strip shell so - // the equal-height contract survives the streamed paint. - const briefingFallback = ( -
- ); - const correlationFallback = ( -
- ); - const trendsFallback = ( -
- ); + // v1.4.36 QA C2 — no `` wrappers below. The mother page is + // `"use client"`, the below-the-fold blocks load via `next/dynamic` + // with `{ ssr: false }` (no Promise-throw on hydrate), and the + // TanStack Query hooks each return their own loading state without + // ever throwing a thenable. Wrapping these in `` would be + // dead code — Suspense never engages and the `loading` props inside + // each section already drive the skeleton. The perceptual win we + // ship is "early-skeleton paint": the page-level `isLoading` gate is + // gone, the hero + each section's own loader skeleton paints inside + // the first paint budget while data fills in. Genuinely streamed + // server children would require a Server-Component refactor; that's + // a v1.5.x track. return (
@@ -253,29 +251,23 @@ export default function InsightsPage() { /> {flags.briefing && ( - - - + )} {flags.correlations && analytics?.correlations && ( - - - + )} - - - +
); }