perf(i18n): stop serializing the full catalogue on public pages
The root layout fed the entire ~254 KB message catalogue to NextIntlClientProvider, which serializes it into the RSC payload of every page. A public page only reads ~59 KB of it; the ~195 KB difference is staff tool copy that only /admin, /admin-next and /mod ever render. The root provider now installs the reduced catalogue and each staff route group re-installs the full one, since a nested NextIntlClientProvider replaces the parent message set rather than merging into it. pages.admin.actions stays public because the shared useServerAction hook runs on public pages too. Measured: 253 KB -> 59 KB of messages per public page (raw JSON). Guard tests cover all three halves: the root keeps using the reduced catalogue, every staff layout installs its own full provider, and no public tree reads a staff-only namespace.
This commit is contained in:
1 parent
d28dde459a
commit
bb3799f705
7 files changed
+136
-18
No files matched your search
@@ -10,7 +10,8 @@ import {
|
||||
Users,
|
||||
} from "lucide-react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { NextIntlClientProvider } from "next-intl";
|
||||
import { getLocale, getMessages, getTranslations } from "next-intl/server";
|
||||
import type { ReactNode } from "react";
|
||||
import { LanguageSwitcher } from "@/components/language-switcher";
|
||||
import Link from "@/components/link";
|
||||
@@ -81,8 +82,13 @@ export default async function ModLayout({ children }: { children: ReactNode }) {
|
||||
{ href: "/mod/team", label: t("nav.team"), icon: Users, show: showTeam },
|
||||
].filter((item) => item.show);
|
||||
|
||||
// The root layout ships the reduced catalogue so public pages do not carry
|
||||
// the ~195 KB of staff-tool strings. Nested providers replace the parent
|
||||
// set rather than merging, so staff route groups re-install the full one.
|
||||
const [locale, messages] = await Promise.all([getLocale(), getMessages()]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<NextIntlClientProvider locale={locale} messages={messages}>
|
||||
{csrfToken ? <meta name="csrf-token" content={csrfToken} /> : null}
|
||||
<div
|
||||
data-admin
|
||||
@@ -140,6 +146,6 @@ export default async function ModLayout({ children }: { children: ReactNode }) {
|
||||
</header>
|
||||
<main className="mx-auto max-w-6xl p-4 sm:p-6">{children}</main>
|
||||
</div>
|
||||
</>
|
||||
</NextIntlClientProvider>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user