Browse Source

feat: reduce first load js size from 500kb to 85kb

Yifei Zhang 2 years ago
parent
commit
ce5abac9fb
4 changed files with 77 additions and 10 deletions
  1. 51 0
      README.md
  2. 3 0
      app/components/home.module.scss
  3. 23 9
      app/components/home.tsx
  4. 0 1
      app/components/ui-lib.tsx

+ 51 - 0
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

+ 3 - 0
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%;
 }

+ 23 - 9
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 <div className={styles['loading-content']}>
+    {!props.noLogo && <BotIcon />}
+    <LoadingIcon />
+  </div>
+}
+
+const Markdown = dynamic(async () => (await import('./markdown')).Markdown, {
+  loading: () => <LoadingIcon />
+})
+
+const Settings = dynamic(async () => (await import('./settings')).Settings, {
+  loading: () => <Loading noLogo />
+})
+
+const Emoji = dynamic(async () => (await import("emoji-picker-react")).Emoji, {
+  loading: () => <LoadingIcon />
+})
 
 export function Avatar(props: { role: Message["role"] }) {
   const config = useChatStore((state) => state.config);
@@ -334,12 +353,7 @@ export function Home() {
   useSwitchTheme();
 
   if (loading) {
-    return (
-      <div>
-        <Avatar role="assistant"></Avatar>
-        <LoadingIcon />
-      </div>
-    );
+    return <Loading />;
   }
 
   return (

+ 0 - 1
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;