perf: run ssrInit() at root layout (#19460)

* wip

* remove ssrInit unneeded

* refactor

* revert unneeded changes

* update booking-page-wrapper layout
This commit is contained in:
Benny Joo
2025-02-25 06:08:23 -05:00
committed by GitHub
parent 307b2946a2
commit 6ea879f265
7 changed files with 25 additions and 38 deletions
+2 -13
View File
@@ -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 (
<PageWrapper
isBookingPage={true}
requiresLicense={false}
nonce={nonce}
themeBasis={null}
dehydratedState={ssr.dehydrate()}>
<PageWrapper isBookingPage={true} requiresLicense={false} nonce={nonce} themeBasis={null}>
{children}
</PageWrapper>
);
+2 -9
View File
@@ -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 (
<PageWrapper requiresLicense={false} nonce={nonce} themeBasis={null} dehydratedState={ssr.dehydrate()}>
<PageWrapper requiresLicense={false} nonce={nonce} themeBasis={null}>
{children}
</PageWrapper>
);
+7 -3
View File
@@ -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<AppRouter>
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 (
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
<QueryClientProvider client={queryClient}>
<HydrateClient state={dehydratedState}>{children}</HydrateClient>
</QueryClientProvider>
</trpc.Provider>
);
};
+5 -1
View File
@@ -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 (
<html
lang={locale}
@@ -159,7 +163,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
"/insights",
]}
/>
<Providers>{children}</Providers>
<Providers dehydratedState={ssr.dehydrate()}>{children}</Providers>
</body>
</html>
);
+7 -2
View File
@@ -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 (
<SessionProvider>
<TrpcProvider>
<TrpcProvider dehydratedState={dehydratedState}>
{!isBookingPage ? <PlainChat /> : null}
{/* @ts-expect-error FIXME remove this comment when upgrading typescript to v5 */}
<CacheProvider>{children}</CacheProvider>
@@ -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;
}>;
+2 -8
View File
@@ -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) => {
</CustomI18nextProvider>
</EventCollectionProvider>
);
const Hydrated = props.dehydratedState ? (
<HydrateClient state={props.dehydratedState}>{RemainingProviders}</HydrateClient>
) : (
RemainingProviders
);
if (props.isBookingPage || isBookingPage) {
return Hydrated;
return RemainingProviders;
}
return (
<>
<DynamicHelpscoutProvider>
<DynamicPostHogProvider>{Hydrated}</DynamicPostHogProvider>
<DynamicPostHogProvider>{RemainingProviders}</DynamicPostHogProvider>
</DynamicHelpscoutProvider>
</>
);