From ce5abac9fbb35999c577ba20621433dcc22c276a Mon Sep 17 00:00:00 2001 From: Yifei Zhang Date: Mon, 20 Mar 2023 15:11:04 +0000 Subject: [PATCH] feat: reduce first load js size from 500kb to 85kb --- README.md | 51 +++++++++++++++++++++++++++++++++ app/components/home.module.scss | 3 ++ app/components/home.tsx | 32 +++++++++++++++------ app/components/ui-lib.tsx | 1 - 4 files changed, 77 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5bc7ca24..ca683240 100644 --- a/README.md +++ b/README.md @@ -36,3 +36,54 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. + +## build log +### raw +Route (app) Size First Load JS +┌ ○ / 449 kB 517 kB +├ λ /api/chat 0 B 0 B +└ ℇ /api/chat-stream 0 B 0 B ++ First Load JS shared by all 68.8 kB + ├ chunks/455-0a9fbb1180548580.js 66.4 kB + ├ chunks/main-app-19b36671ec6a549e.js 204 B + └ chunks/webpack-dd78d1150b6f4f4a.js 2.15 kB + +Route (pages) Size First Load JS +─ ○ /404 179 B 84.6 kB ++ First Load JS shared by all 84.4 kB + ├ chunks/main-303e01cd7449e20b.js 82.1 kB + ├ chunks/pages/_app-907dedfd0e4177db.js 192 B + +### dynamic markdown +Route (app) Size First Load JS +┌ ○ / 64.2 kB 133 kB +├ λ /api/chat 0 B 0 B +└ ℇ /api/chat-stream 0 B 0 B ++ First Load JS shared by all 68.9 kB + ├ chunks/455-0a9fbb1180548580.js 66.4 kB + ├ chunks/main-app-19b36671ec6a549e.js 204 B + └ chunks/webpack-3b3874680bea117d.js 2.26 kB + +Route (pages) Size First Load JS +─ ○ /404 179 B 84.7 kB ++ First Load JS shared by all 84.5 kB + ├ chunks/main-303e01cd7449e20b.js 82.1 kB + ├ chunks/pages/_app-907dedfd0e4177db.js 192 B + └ chunks/webpack-3b3874680bea117d.js 2.26 kB + +### dynamic emoji +Route (app) Size First Load JS +┌ ○ / 16.1 kB 85 kB +├ λ /api/chat 0 B 0 B +└ ℇ /api/chat-stream 0 B 0 B ++ First Load JS shared by all 68.9 kB + ├ chunks/455-0a9fbb1180548580.js 66.4 kB + ├ chunks/main-app-19b36671ec6a549e.js 204 B + └ chunks/webpack-2bfaffd64d73d7a1.js 2.33 kB + +Route (pages) Size First Load JS +─ ○ /404 179 B 84.8 kB ++ First Load JS shared by all 84.6 kB + ├ chunks/main-303e01cd7449e20b.js 82.1 kB + ├ chunks/pages/_app-907dedfd0e4177db.js 192 B + └ chunks/webpack-2bfaffd64d73d7a1.js 2.33 kB \ No newline at end of file diff --git a/app/components/home.module.scss b/app/components/home.module.scss index 0ef3d75d..2a5a85bb 100644 --- a/app/components/home.module.scss +++ b/app/components/home.module.scss @@ -342,6 +342,9 @@ .loading-content { display: flex; + flex-direction: column; justify-content: center; align-items: center; + height: 100%; + width: 100%; } \ No newline at end of file diff --git a/app/components/home.tsx b/app/components/home.tsx index f1e8ee0d..32e6b233 100644 --- a/app/components/home.tsx +++ b/app/components/home.tsx @@ -1,11 +1,9 @@ "use client"; import { useState, useRef, useEffect } from "react"; -import { Emoji } from "emoji-picker-react"; import { IconButton } from "./button"; import styles from "./home.module.scss"; -import { Markdown } from './markdown' import SettingsIcon from "../icons/settings.svg"; import GithubIcon from "../icons/github.svg"; @@ -23,10 +21,31 @@ import CopyIcon from "../icons/copy.svg"; import DownloadIcon from "../icons/download.svg"; import { Message, SubmitKey, useChatStore, ChatSession } from "../store"; -import { Settings } from "./settings"; import { showModal } from "./ui-lib"; import { copyToClipboard, downloadAs, isIOS } from "../utils"; +import dynamic from "next/dynamic"; + +export function Loading(props: { + noLogo?: boolean +}) { + return
+ {!props.noLogo && } + +
+} + +const Markdown = dynamic(async () => (await import('./markdown')).Markdown, { + loading: () => +}) + +const Settings = dynamic(async () => (await import('./settings')).Settings, { + loading: () => +}) + +const Emoji = dynamic(async () => (await import("emoji-picker-react")).Emoji, { + loading: () => +}) export function Avatar(props: { role: Message["role"] }) { const config = useChatStore((state) => state.config); @@ -334,12 +353,7 @@ export function Home() { useSwitchTheme(); if (loading) { - return ( -
- - -
- ); + return ; } return ( diff --git a/app/components/ui-lib.tsx b/app/components/ui-lib.tsx index 34604d4a..fff1af31 100644 --- a/app/components/ui-lib.tsx +++ b/app/components/ui-lib.tsx @@ -2,7 +2,6 @@ import styles from "./ui-lib.module.scss"; import LoadingIcon from "../icons/three-dots.svg"; import CloseIcon from "../icons/close.svg"; import { createRoot } from 'react-dom/client' -import { IconButton } from "./button"; export function Popover(props: { children: JSX.Element;