Skip to content

Commit d7f6321

Browse files
authored
feat: Add code splitting to reduce bundle size (#1285)
This splits our pages to use separate JavaScript bundles. It initially splits the terminal, which reduces our primary bundle size by ~400KB. We should do this for all pages, but that can come in a future change. This leaves the loading page empty for now, which I think is fine. None of our pages are large enough that the blank screen temporarily would be concerning.
1 parent f911c8a commit d7f6321

File tree

4 files changed

+98
-89
lines changed

4 files changed

+98
-89
lines changed

site/src/AppRouter.tsx

Lines changed: 89 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -17,133 +17,136 @@ import { SettingsPage } from "./pages/SettingsPage/SettingsPage"
1717
import { CreateWorkspacePage } from "./pages/TemplatesPages/OrganizationPage/TemplatePage/CreateWorkspacePage"
1818
import { TemplatePage } from "./pages/TemplatesPages/OrganizationPage/TemplatePage/TemplatePage"
1919
import { TemplatesPage } from "./pages/TemplatesPages/TemplatesPage"
20-
import { TerminalPage } from "./pages/TerminalPage/TerminalPage"
2120
import { CreateUserPage } from "./pages/UsersPage/CreateUserPage/CreateUserPage"
2221
import { UsersPage } from "./pages/UsersPage/UsersPage"
2322
import { WorkspacePage } from "./pages/WorkspacesPage/WorkspacesPage"
2423

25-
export const AppRouter: React.FC = () => (
26-
<Routes>
27-
<Route path="/">
28-
<Route
29-
index
30-
element={
31-
<RequireAuth>
32-
<IndexPage />
33-
</RequireAuth>
34-
}
35-
/>
36-
37-
<Route path="login" element={<LoginPage />} />
38-
<Route path="healthz" element={<HealthzPage />} />
39-
<Route
40-
path="cli-auth"
41-
element={
42-
<RequireAuth>
43-
<CliAuthenticationPage />
44-
</RequireAuth>
45-
}
46-
/>
24+
const TerminalPage = React.lazy(() => import("./pages/TerminalPage/TerminalPage"))
4725

48-
<Route path="templates">
26+
export const AppRouter: React.FC = () => (
27+
<React.Suspense fallback={<></>}>
28+
<Routes>
29+
<Route path="/">
4930
<Route
5031
index
5132
element={
52-
<AuthAndFrame>
53-
<TemplatesPage />
54-
</AuthAndFrame>
33+
<RequireAuth>
34+
<IndexPage />
35+
</RequireAuth>
36+
}
37+
/>
38+
39+
<Route path="login" element={<LoginPage />} />
40+
<Route path="healthz" element={<HealthzPage />} />
41+
<Route
42+
path="cli-auth"
43+
element={
44+
<RequireAuth>
45+
<CliAuthenticationPage />
46+
</RequireAuth>
5547
}
5648
/>
57-
<Route path=":organization/:template">
49+
50+
<Route path="templates">
51+
<Route
52+
index
53+
element={
54+
<AuthAndFrame>
55+
<TemplatesPage />
56+
</AuthAndFrame>
57+
}
58+
/>
59+
<Route path=":organization/:template">
60+
<Route
61+
index
62+
element={
63+
<AuthAndFrame>
64+
<TemplatePage />
65+
</AuthAndFrame>
66+
}
67+
/>
68+
<Route
69+
path="create"
70+
element={
71+
<RequireAuth>
72+
<CreateWorkspacePage />
73+
</RequireAuth>
74+
}
75+
/>
76+
</Route>
77+
</Route>
78+
79+
<Route path="workspaces">
80+
<Route
81+
path=":workspace"
82+
element={
83+
<AuthAndFrame>
84+
<WorkspacePage />
85+
</AuthAndFrame>
86+
}
87+
/>
88+
</Route>
89+
90+
<Route path="users">
5891
<Route
5992
index
6093
element={
6194
<AuthAndFrame>
62-
<TemplatePage />
95+
<UsersPage />
6396
</AuthAndFrame>
6497
}
6598
/>
6699
<Route
67100
path="create"
68101
element={
69102
<RequireAuth>
70-
<CreateWorkspacePage />
103+
<CreateUserPage />
71104
</RequireAuth>
72105
}
73106
/>
74107
</Route>
75-
</Route>
76-
77-
<Route path="workspaces">
78108
<Route
79-
path=":workspace"
109+
path="orgs"
80110
element={
81111
<AuthAndFrame>
82-
<WorkspacePage />
112+
<OrgsPage />
83113
</AuthAndFrame>
84114
}
85115
/>
86-
</Route>
87-
88-
<Route path="users">
89116
<Route
90-
index
117+
path="settings"
91118
element={
92119
<AuthAndFrame>
93-
<UsersPage />
120+
<SettingsPage />
94121
</AuthAndFrame>
95122
}
96123
/>
97-
<Route
98-
path="create"
99-
element={
100-
<RequireAuth>
101-
<CreateUserPage />
102-
</RequireAuth>
103-
}
104-
/>
105-
</Route>
106-
<Route
107-
path="orgs"
108-
element={
109-
<AuthAndFrame>
110-
<OrgsPage />
111-
</AuthAndFrame>
112-
}
113-
/>
114-
<Route
115-
path="settings"
116-
element={
117-
<AuthAndFrame>
118-
<SettingsPage />
119-
</AuthAndFrame>
120-
}
121-
/>
122124

123-
<Route path="preferences" element={<PreferencesLayout />}>
124-
<Route path="account" element={<AccountPage />} />
125-
<Route path="security" element={<SecurityPage />} />
126-
<Route path="ssh-keys" element={<SSHKeysPage />} />
127-
<Route path="linked-accounts" element={<LinkedAccountsPage />} />
128-
</Route>
125+
<Route path="preferences" element={<PreferencesLayout />}>
126+
<Route path="account" element={<AccountPage />} />
127+
<Route path="security" element={<SecurityPage />} />
128+
<Route path="ssh-keys" element={<SSHKeysPage />} />
129+
<Route path="linked-accounts" element={<LinkedAccountsPage />} />
130+
</Route>
129131

130-
<Route path=":username">
131-
<Route path=":workspace">
132-
<Route
133-
path="terminal"
134-
element={
135-
<RequireAuth>
136-
<TerminalPage />
137-
</RequireAuth>
138-
}
139-
/>
132+
<Route path=":username">
133+
<Route path=":workspace">
134+
<Route
135+
path="terminal"
136+
element={
137+
<RequireAuth>
138+
<TerminalPage />
139+
</RequireAuth>
140+
}
141+
/>
142+
</Route>
140143
</Route>
141-
</Route>
142144

143-
{/* Using path="*"" means "match anything", so this route
145+
{/* Using path="*"" means "match anything", so this route
144146
acts like a catch-all for URLs that we don't have explicit
145147
routes for. */}
146-
<Route path="*" element={<NotFoundPage />} />
147-
</Route>
148-
</Routes>
148+
<Route path="*" element={<NotFoundPage />} />
149+
</Route>
150+
</Routes>
151+
</React.Suspense>
149152
)

site/src/pages/TerminalPage/TerminalPage.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { TextDecoder, TextEncoder } from "util"
88
import { ReconnectingPTYRequest } from "../../api/types"
99
import { history, MockWorkspaceAgent, render } from "../../testHelpers"
1010
import { server } from "../../testHelpers/server"
11-
import { Language, TerminalPage } from "./TerminalPage"
11+
import TerminalPage, { Language } from "./TerminalPage"
1212

1313
Object.defineProperty(window, "matchMedia", {
1414
writable: true,

site/src/pages/TerminalPage/TerminalPage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const Language = {
1717
websocketErrorMessagePrefix: "WebSocket failed: ",
1818
}
1919

20-
export const TerminalPage: React.FC<{
20+
const TerminalPage: React.FC<{
2121
readonly renderer?: XTerm.RendererType
2222
}> = ({ renderer }) => {
2323
const location = useLocation()
@@ -200,6 +200,8 @@ export const TerminalPage: React.FC<{
200200
)
201201
}
202202

203+
export default TerminalPage
204+
203205
const useStyles = makeStyles(() => ({
204206
overlay: {
205207
position: "absolute",

site/tsconfig.prod.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
{
22
"extends": "./tsconfig.json",
3-
"exclude": ["node_modules", "_jest", "**/*.stories.tsx", "**/*.test.tsx"]
3+
"exclude": ["node_modules", "_jest", "**/*.stories.tsx", "**/*.test.tsx"],
4+
"compilerOptions": {
5+
// https://github.com/webpack/webpack/issues/5703#issuecomment-357512412
6+
"module": "esnext"
7+
}
48
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy