Skip to content

FCP regression and pending component flashing on static pages (Next.js -> TanStack Start migration) #462

Description

@aymericzip

I am migrating the documentation website for Intlayer from Next.js to TanStack Start. All pages are fully static with no authentication barriers. Following the migration, the application experiences a ~30% regression in First Contentful Paint (FCP) and flashes the defaultPendingComponent (resulting in a black screen) on every route navigation.

It appears the routing mechanism waits for the loader to fetch data from the server before rendering the page, blocking the UI despite preloading and suspense configurations.

Screen.Recording.2026-06-08.at.7.16.36.PM.mov

Nextjs Lighthouse result:
Image

Tanstack Lighthouse result:
Image

Repositories & Deployments:

Current Configuration & Setup:

  • Prerendering: Enabled.

  • Hydration: No hydration errors present.

  • Code-splitting: The first section of the landing page is statically imported. The subsequent sections and documentation navbars are optimized using lazy imports to isolate the initial paint.

  • Suspense: Boundaries are configured.

  • Router configuration (/src/router.tsx):

  • defaultStaleTime: Infinity

  • defaultPendingMs: 0

  • defaultPreload: 'intent'

  • Navigation links: Set to preload: 'viewport'.

Loader Implementation Example:
The issue is most prominent on the documentation pages. Below is the current setup for the catch-all docs route, which fetches the markdown content and navigation data concurrently:

// /src/routes/{-$locale}/_docs/doc/$.tsx

export const Route = createFileRoute('/{-$locale}/_docs/doc/$')({
  loader: async ({ params }) => {
    const { locale = defaultLocale } = params;
    const slugsStr = params['*'] || '';
    const slugs = slugsStr ? slugsStr.split('/') : [];

    const [result, navData] = await Promise.all([
      loadDocPage({ data: { locale, slugs } }),
      loadNavData({ data: { locale } }),
    ]);
    
    return { result, navData };
  }
})

Hypothesis & Feature Request:
The core problem seems to be the absence of a direct generateStaticParams equivalent in TanStack Start for fully static build-time data retrieval. The loader executes and blocks the UI transition instead of instantly serving pre-computed static data.

Are there specific configurations missing to force pure build-time data fetching and instant client-side transitions for static routes, or is this a current limitation of the framework's prerendering architecture?

--

CC @tornado-softwares

Metadata

Metadata

Assignees

No one assigned

    Labels

    help neededissue that need helpswebsiteRelated to the Intlayer website / landing page

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions