Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⚡️ perf: make app page as static route to improve performance #5478

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
50 changes: 0 additions & 50 deletions src/app/(main)/chat/(workspace)/page.tsx

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { Center } from 'react-layout-kit';
import BrandWatermark from '@/components/BrandWatermark';
import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/server/responsive';
import { DynamicLayoutProps } from '@/types/next';
import { RouteVariants } from '@/utils/server/routeVariants';

import Category from './features/Category';
import UserBanner from './features/UserBanner';
Expand All @@ -17,10 +18,10 @@ export const generateMetadata = async () => {
});
};

const Page = async () => {
const mobile = await isMobileDevice();
const Page = async (props: DynamicLayoutProps) => {
const isMobile = await RouteVariants.getIsMobile(props);

if (!mobile) return redirect('/chat');
if (!isMobile) return redirect('/chat');

return (
<>
Expand All @@ -36,3 +37,5 @@ const Page = async () => {
Page.displayName = 'Me';

export default Page;

export const dynamic = 'force-static';
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { redirect } from 'next/navigation';

import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/server/responsive';
import { DynamicLayoutProps } from '@/types/next';
import { RouteVariants } from '@/utils/server/routeVariants';

import Category from './features/Category';

Expand All @@ -14,14 +15,16 @@ export const generateMetadata = async () => {
});
};

const Page = async () => {
const mobile = await isMobileDevice();
const Page = async (props: DynamicLayoutProps) => {
const isMobile = await RouteVariants.getIsMobile(props);

if (!mobile) return redirect('/chat');
if (!isMobile) return redirect('/chat');

return <Category />;
};

Page.displayName = 'MeData';

export default Page;

export const dynamic = 'force-static';
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Cell, { CellProps } from '@/components/Cell';
import { isDeprecatedEdition } from '@/const/version';
import { ProfileTabs } from '@/store/global/initialState';
import { useUserStore } from '@/store/user';
import { authSelectors } from '@/store/user/slices/auth/selectors';
import { authSelectors } from '@/store/user/selectors';

const Category = memo(() => {
const [isLogin, enableAuth, isLoginWithClerk, signOut] = useUserStore((s) => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { redirect } from 'next/navigation';

import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/server/responsive';
import { DynamicLayoutProps } from '@/types/next';
import { RouteVariants } from '@/utils/server/routeVariants';

import Category from './features/Category';

Expand All @@ -15,14 +16,16 @@ export const generateMetadata = async () => {
});
};

const Page = async () => {
const mobile = await isMobileDevice();
const Page = async (props: DynamicLayoutProps) => {
const isMobile = await RouteVariants.getIsMobile(props);

if (!mobile) return redirect('/profile');
if (!isMobile) return redirect('/profile');

return <Category />;
};

Page.displayName = 'MeProfile';

export default Page;

export const dynamic = 'force-static';
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { redirect } from 'next/navigation';

import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/server/responsive';
import { DynamicLayoutProps } from '@/types/next';
import { RouteVariants } from '@/utils/server/routeVariants';

import Category from './features/Category';

Expand All @@ -15,14 +16,16 @@ export const generateMetadata = async () => {
});
};

const Page = async () => {
const mobile = await isMobileDevice();
const Page = async (props: DynamicLayoutProps) => {
const isMobile = await RouteVariants.getIsMobile(props);

if (!mobile) return redirect('/settings/common');
if (!isMobile) return redirect('/settings/common');

return <Category />;
};

Page.displayName = 'MeSettings';

export default Page;

export const dynamic = 'force-static';
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { SideNav } from '@lobehub/ui';
import { parseAsBoolean, useQueryState } from 'nuqs';
import { memo } from 'react';

import { withSuspense } from '@/components/withSuspense';
import { useActiveTabKey } from '@/hooks/useActiveTabKey';
import { useGlobalStore } from '@/store/global';
import { systemStatusSelectors } from '@/store/global/selectors';
Expand Down Expand Up @@ -39,4 +40,4 @@ const Nav = memo(() => {

Nav.displayName = 'DesktopNav';

export default Nav;
export default withSuspense(Nav);
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { rgba } from 'polished';
import { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';

import { withSuspense } from '@/components/withSuspense';
import { useActiveTabKey } from '@/hooks/useActiveTabKey';
import { SidebarTabKey } from '@/store/global/initialState';
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
Expand Down Expand Up @@ -75,6 +76,6 @@ const NavBar = memo(() => {
return <MobileTabBar activeKey={activeKey} className={styles.container} items={items} />;
});

NavBar.displayName = 'NavBar';
NavBar.displayName = 'MobileNav';

export default NavBar;
export default withSuspense(NavBar);
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ const MainLayout = ServerLayout({ Desktop, Mobile });
MainLayout.displayName = 'ChangelogLayout';

export default MainLayout;

export const dynamic = 'force-static';
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
'use client';

import { useRouter } from 'next/navigation';
import { useLayoutEffect } from 'react';

import { useQueryRoute } from '@/hooks/useQueryRoute';

/**
* @description: Changelog Modal (intercepting routes fallback when hard refresh)
* @example: /changelog/modal => /changelog
* @refs: https://github.com/lobehub/lobe-chat/discussions/2295#discussioncomment-9290942
*/

const ChangelogModalFallback = () => {
const router = useQueryRoute();
const router = useRouter();

useLayoutEffect(() => {
router.replace('/changelog');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Fragment, Suspense } from 'react';
import { Flexbox } from 'react-layout-kit';
import urlJoin from 'url-join';

import Pagination from '@/app/@modal/(.)changelog/modal/features/Pagination';
import Pagination from '@/app/[variants]/@modal/(.)changelog/modal/features/Pagination';
import StructuredData from '@/components/StructuredData';
import { serverFeatureFlags } from '@/config/featureFlags';
import { BRANDING_NAME } from '@/const/branding';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { isMobileDevice } from '@/utils/server/responsive';
import { DynamicLayoutProps } from '@/types/next';
import { RouteVariants } from '@/utils/server/routeVariants';

import ChatHydration from './features/ChatHydration';
import ChatInput from './features/ChatInput';
import ChatList from './features/ChatList';
import ThreadHydration from './features/ThreadHydration';
import ZenModeToast from './features/ZenModeToast';

const ChatConversation = async () => {
const mobile = await isMobileDevice();
const ChatConversation = async (props: DynamicLayoutProps) => {
const isMobile = await RouteVariants.getIsMobile(props);

return (
<>
<ZenModeToast />
<ChatList mobile={mobile} />
<ChatInput mobile={mobile} />
<ChatList mobile={isMobile} />
<ChatInput mobile={isMobile} />
<ChatHydration />
<ThreadHydration />
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import React, { Suspense, lazy } from 'react';

import Loading from '@/components/Loading/BrandTextLoading';
import { isMobileDevice } from '@/utils/server/responsive';
import { DynamicLayoutProps } from '@/types/next';
import { RouteVariants } from '@/utils/server/routeVariants';

import Desktop from './_layout/Desktop';
import Mobile from './_layout/Mobile';

const PortalBody = lazy(() => import('@/features/Portal/router'));

const Inspector = async () => {
const mobile = await isMobileDevice();
const Inspector = async (props: DynamicLayoutProps) => {
const isMobile = await RouteVariants.getIsMobile(props);

const Layout = mobile ? Mobile : Desktop;
const Layout = isMobile ? Mobile : Desktop;

return (
<Suspense fallback={<Loading />}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// import TopicListContent from './features/TopicListContent';
import React, { Suspense, lazy } from 'react';

import { isMobileDevice } from '@/utils/server/responsive';
import { DynamicLayoutProps } from '@/types/next';
import { RouteVariants } from '@/utils/server/routeVariants';

import Desktop from './_layout/Desktop';
import Mobile from './_layout/Mobile';
Expand All @@ -10,14 +11,14 @@ import SystemRole from './features/SystemRole';

const TopicContent = lazy(() => import('./features/TopicListContent'));

const Topic = async () => {
const mobile = await isMobileDevice();
const Topic = async (props: DynamicLayoutProps) => {
const isMobile = await RouteVariants.getIsMobile(props);

const Layout = mobile ? Mobile : Desktop;
const Layout = isMobile ? Mobile : Desktop;

return (
<>
{!mobile && <SystemRole />}
{!isMobile && <SystemRole />}
<Layout>
<Suspense fallback={<SkeletonList />}>
<TopicContent />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { MobileNavBar } from '@lobehub/ui/mobile';
import { memo, useState } from 'react';

import { useInitAgentConfig } from '@/app/(main)/chat/(workspace)/_layout/useInitAgentConfig';
import { useInitAgentConfig } from '@/app/[variants]/(main)/chat/(workspace)/_layout/useInitAgentConfig';
import { INBOX_SESSION_ID } from '@/const/session';
import { useQueryRoute } from '@/hooks/useQueryRoute';
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
Expand Down
56 changes: 56 additions & 0 deletions src/app/[variants]/(main)/chat/(workspace)/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// import { Suspense } from 'react';
import StructuredData from '@/components/StructuredData';
// import { serverFeatureFlags } from '@/config/featureFlags';
import { BRANDING_NAME } from '@/const/branding';
import { ldModule } from '@/server/ld';
import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation';
import { DynamicLayoutProps } from '@/types/next';
import { RouteVariants } from '@/utils/server/routeVariants';

import PageTitle from '../features/PageTitle';
// import Changelog from './features/ChangelogModal';
import TelemetryNotification from './features/TelemetryNotification';

export const generateMetadata = async (props: DynamicLayoutProps) => {
const locale = await RouteVariants.getLocale(props);

const { t } = await translation('metadata', locale);
return metadataModule.generate({
description: t('chat.description', { appName: BRANDING_NAME }),
title: t('chat.title', { appName: BRANDING_NAME }),
url: '/chat',
});
};

const Page = async (props: DynamicLayoutProps) => {
// const { hideDocs, showChangelog } = serverFeatureFlags();

const { isMobile, locale } = await RouteVariants.getVariantsFromProps(props);
const { t } = await translation('metadata', locale);

const ld = ldModule.generate({
description: t('chat.description', { appName: BRANDING_NAME }),
title: t('chat.title', { appName: BRANDING_NAME }),
url: '/chat',
});

return (
<>
<StructuredData ld={ld} />
<PageTitle />
<TelemetryNotification mobile={isMobile} />
{/*{showChangelog && !hideDocs && !isMobile && (*/}
{/* <Suspense>*/}
{/* <Changelog />*/}
{/* </Suspense>*/}
{/*)}*/}
</>
);
};

Page.displayName = 'Chat';

export default Page;

export const dynamic = 'force-static';
Loading
Loading