From 6ea879f26550e41d0c85443d63a0de1b79342e34 Mon Sep 17 00:00:00 2001 From: Benny Joo Date: Tue, 25 Feb 2025 06:08:23 -0500 Subject: [PATCH] perf: run `ssrInit()` at root layout (#19460) * wip * remove ssrInit unneeded * refactor * revert unneeded changes * update booking-page-wrapper layout --- apps/web/app/(booking-page-wrapper)/layout.tsx | 15 ++------------- apps/web/app/(use-page-wrapper)/layout.tsx | 11 ++--------- apps/web/app/_trpc/trpc-provider.tsx | 10 +++++++--- apps/web/app/layout.tsx | 6 +++++- apps/web/app/providers.tsx | 9 +++++++-- apps/web/components/PageWrapperAppDir.tsx | 2 -- apps/web/lib/app-providers-app-dir.tsx | 10 ++-------- 7 files changed, 25 insertions(+), 38 deletions(-) diff --git a/apps/web/app/(booking-page-wrapper)/layout.tsx b/apps/web/app/(booking-page-wrapper)/layout.tsx index 1dd819f322..0594258a49 100644 --- a/apps/web/app/(booking-page-wrapper)/layout.tsx +++ b/apps/web/app/(booking-page-wrapper)/layout.tsx @@ -1,24 +1,13 @@ -import { cookies, headers } from "next/headers"; - -import { buildLegacyCtx } from "@lib/buildLegacyCtx"; +import { headers } from "next/headers"; import PageWrapper from "@components/PageWrapperAppDir"; -import { ssrInit } from "@server/lib/ssr"; - export default async function BookingPageWrapperLayout({ children }: { children: React.ReactNode }) { const h = headers(); const nonce = h.get("x-nonce") ?? undefined; - const context = buildLegacyCtx(h, cookies(), {}, {}); - const ssr = await ssrInit(context); return ( - + {children} ); diff --git a/apps/web/app/(use-page-wrapper)/layout.tsx b/apps/web/app/(use-page-wrapper)/layout.tsx index 40aeb0db27..77307297e0 100644 --- a/apps/web/app/(use-page-wrapper)/layout.tsx +++ b/apps/web/app/(use-page-wrapper)/layout.tsx @@ -1,20 +1,13 @@ -import { cookies, headers } from "next/headers"; - -import { buildLegacyCtx } from "@lib/buildLegacyCtx"; +import { headers } from "next/headers"; import PageWrapper from "@components/PageWrapperAppDir"; -import { ssrInit } from "@server/lib/ssr"; - export default async function PageWrapperLayout({ children }: { children: React.ReactNode }) { const h = headers(); const nonce = h.get("x-nonce") ?? undefined; - const context = buildLegacyCtx(headers(), cookies(), {}, {}); - const ssr = await ssrInit(context); - return ( - + {children} ); diff --git a/apps/web/app/_trpc/trpc-provider.tsx b/apps/web/app/_trpc/trpc-provider.tsx index cc339e9cec..eacb9be901 100644 --- a/apps/web/app/_trpc/trpc-provider.tsx +++ b/apps/web/app/_trpc/trpc-provider.tsx @@ -1,6 +1,7 @@ "use client"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { type DehydratedState, QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { HydrateClient } from "app/_trpc/HydrateClient"; import { trpc } from "app/_trpc/client"; import { useState } from "react"; import superjson from "superjson"; @@ -42,9 +43,10 @@ const isTRPCClientError = (cause: unknown): cause is TRPCClientError type Props = { children: React.ReactNode; + dehydratedState: DehydratedState; }; -export const TrpcProvider = ({ children }: Props) => { +export const TrpcProvider = ({ children, dehydratedState }: Props) => { const [queryClient] = useState( () => new QueryClient({ @@ -126,7 +128,9 @@ export const TrpcProvider = ({ children }: Props) => { return ( - {children} + + {children} + ); }; diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index cbebcbeaf2..a178899ac7 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -7,8 +7,11 @@ import React from "react"; import { getLocale } from "@calcom/features/auth/lib/getLocale"; import { IconSprites } from "@calcom/ui"; +import { buildLegacyCtx } from "@lib/buildLegacyCtx"; import { prepareRootMetadata } from "@lib/metadata"; +import { ssrInit } from "@server/lib/ssr"; + import "../styles/globals.css"; import { SpeculationRules } from "./SpeculationRules"; import { Providers } from "./providers"; @@ -56,6 +59,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo ? getFallbackProps() : await getInitialProps(fullUrl); + const ssr = await ssrInit(buildLegacyCtx(h, cookies(), {}, {})); return ( - {children} + {children} ); diff --git a/apps/web/app/providers.tsx b/apps/web/app/providers.tsx index 15e462e6a4..e218da6834 100644 --- a/apps/web/app/providers.tsx +++ b/apps/web/app/providers.tsx @@ -1,5 +1,6 @@ "use client"; +import { type DehydratedState } from "@tanstack/react-query"; import { TrpcProvider } from "app/_trpc/trpc-provider"; import { SessionProvider } from "next-auth/react"; import CacheProvider from "react-inlinesvg/provider"; @@ -7,12 +8,16 @@ import CacheProvider from "react-inlinesvg/provider"; import useIsBookingPage from "@lib/hooks/useIsBookingPage"; import PlainChat from "@lib/plain/dynamicProvider"; -export function Providers({ children }: { children: React.ReactNode }) { +type ProvidersProps = { + children: React.ReactNode; + dehydratedState: DehydratedState; +}; +export function Providers({ children, dehydratedState }: ProvidersProps) { const isBookingPage = useIsBookingPage(); return ( - + {!isBookingPage ? : null} {/* @ts-expect-error FIXME remove this comment when upgrading typescript to v5 */} {children} diff --git a/apps/web/components/PageWrapperAppDir.tsx b/apps/web/components/PageWrapperAppDir.tsx index a85bac21c1..f49824c549 100644 --- a/apps/web/components/PageWrapperAppDir.tsx +++ b/apps/web/components/PageWrapperAppDir.tsx @@ -1,6 +1,5 @@ "use client"; -import { type DehydratedState } from "@tanstack/react-query"; import type { SSRConfig } from "next-i18next"; // import I18nLanguageHandler from "@components/I18nLanguageHandler"; import { usePathname } from "next/navigation"; @@ -17,7 +16,6 @@ export type PageWrapperProps = Readonly<{ requiresLicense: boolean; nonce: string | undefined; themeBasis: string | null; - dehydratedState?: DehydratedState; isBookingPage?: boolean; i18n?: SSRConfig; }>; diff --git a/apps/web/lib/app-providers-app-dir.tsx b/apps/web/lib/app-providers-app-dir.tsx index bec6cc812d..87d4784ea8 100644 --- a/apps/web/lib/app-providers-app-dir.tsx +++ b/apps/web/lib/app-providers-app-dir.tsx @@ -1,5 +1,4 @@ import { TooltipProvider } from "@radix-ui/react-tooltip"; -import { HydrateClient } from "app/_trpc/HydrateClient"; import { dir } from "i18next"; import type { Session } from "next-auth"; import { useSession } from "next-auth/react"; @@ -281,20 +280,15 @@ const AppProviders = (props: PageWrapperProps) => { ); - const Hydrated = props.dehydratedState ? ( - {RemainingProviders} - ) : ( - RemainingProviders - ); if (props.isBookingPage || isBookingPage) { - return Hydrated; + return RemainingProviders; } return ( <> - {Hydrated} + {RemainingProviders} );