@wular/pnext 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -20
- package/package.json +3 -2
- package/reference/data/bench.json +513 -0
- package/reference/performance.md +75 -48
- package/src/api/router/runtime.ts +60 -21
- package/src/cache/context.ts +4 -1
- package/src/cli/build.ts +37 -5
- package/src/cli/dev.ts +6 -0
- package/src/cli/index.ts +17 -3
- package/src/cli/request-pipeline.ts +1340 -0
- package/src/cli/server-entry.ts +180 -0
- package/src/cli/start.ts +39 -1311
- package/src/client/build.ts +59 -20
- package/src/client/chunk-fold.ts +40 -0
- package/src/client/compat-surface.ts +175 -0
- package/src/client/entry.ts +67 -52
- package/src/compat/actions/action-client.ts +8 -1
- package/src/compat/actions/action-dispatch.ts +11 -1
- package/src/compat/actions/discovery.ts +23 -6
- package/src/compat/bundler/optimize-package-imports.ts +5 -1
- package/src/compat/bundler/worker.ts +2 -1
- package/src/compat/client/errors/bare-boundary.ts +32 -0
- package/src/compat/client/errors/error-boundary.ts +1 -15
- package/src/compat/client/errors/primitive-throw.ts +16 -0
- package/src/compat/client/link-status.ts +1 -1
- package/src/compat/css/lightningcss.ts +2 -1
- package/src/compat/css/modules.ts +4 -3
- package/src/compat/lifecycle/instrumentation-client.ts +1 -1
- package/src/compat/lifecycle/instrumentation.ts +5 -2
- package/src/compat/next/config-loader.ts +33 -5
- package/src/compat/next/dynamic.tsx +9 -5
- package/src/compat/next/link-validation-transform.ts +5 -1
- package/src/compat/next/link.tsx +51 -58
- package/src/compat/pages/client-plugin.ts +2 -1
- package/src/compat/react/action-state.ts +159 -0
- package/src/compat/react/client-lite.ts +74 -0
- package/src/compat/react/hooks-extra.ts +92 -0
- package/src/compat/react/parity.ts +128 -0
- package/src/compat/react/preact.ts +33 -420
- package/src/compat/react/server-inserted-html.ts +14 -7
- package/src/compat/react/use.ts +72 -0
- package/src/compat/register/actions.ts +27 -7
- package/src/compat/register/segment.ts +16 -6
- package/src/config.ts +15 -1
- package/src/css/build.ts +13 -2
- package/src/dev/imports.ts +34 -5
- package/src/dev/module-cache.ts +19 -0
- package/src/dev/module-transform.ts +7 -1
- package/src/dev/server.ts +91 -22
- package/src/dynamic/source.ts +36 -27
- package/src/ppr.ts +5 -4
- package/src/proxy.ts +5 -1
- package/src/render/island-context.ts +21 -3
- package/src/render/renderer.ts +102 -26
- package/src/resolve/engine.ts +12 -2
- package/src/resolve/scan-facts.ts +239 -1
- package/src/routing/href.ts +4 -5
- package/src/routing/routes.ts +26 -41
- package/src/runtime/server.ts +8 -4
- package/src/runtime/vendor.ts +1 -1
- package/src/typegen.ts +3 -3
- package/src/utils/esbuild.ts +58 -0
- package/src/utils/fs.ts +14 -2
- package/src/utils/native-require.ts +28 -0
package/README.md
CHANGED
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
# pnext
|
|
4
4
|
|
|
5
|
-
**A fast little framework for server-first React apps, fully compatible with Next.js.**
|
|
5
|
+
**A fast little framework for server-first React apps, fully compatible with Next.js.**[<sup>1</sup>](./reference/compat.md)
|
|
6
6
|
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
|
-
Server-rendered pages ship **0 KB** of JavaScript — **~1 KB gzip** with client-side navigation and prefetching. Interactive pages hydrate on Preact for **~7.5 KB** of framework, or **~12.5 KB** with React compatibility. Everything is instant: the dev server starts **~3× faster** than Next's on **~4× less memory**, and production builds run **4.5–10× faster**. The Next.js App Router compatibility is validated against Next's own test suite, 4,400+ assertions passing.
|
|
10
|
-
|
|
11
9
|
## Getting started
|
|
12
10
|
|
|
13
11
|
A new app:
|
|
@@ -16,7 +14,7 @@ A new app:
|
|
|
16
14
|
bunx @wular/pnext create my-app
|
|
17
15
|
```
|
|
18
16
|
|
|
19
|
-
Migrating a Next.js app
|
|
17
|
+
Migrating a Next.js app? This rewrites scripts and config in place, scans your source, and reports anything that needs a look (it never edits your code):
|
|
20
18
|
|
|
21
19
|
```sh
|
|
22
20
|
bunx @wular/pnext migrate
|
|
@@ -24,27 +22,85 @@ bunx @wular/pnext migrate
|
|
|
24
22
|
|
|
25
23
|
Or by hand: `bun add -d @wular/pnext`, then `pnext dev`.
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
## Incremental by design
|
|
26
|
+
|
|
27
|
+
Server-rendered pages ship **0 KB** of JavaScript, or **~1 KB gzip** if you want client-side navigation and prefetching. Interactive pages hydrate on Preact for **~7.5 KB** of framework, **~12.5 KB** with React compatibility. And everything is instant: the first page in dev renders **11–13.5× faster** than Next's on **3.4–3.8× less memory**, and production builds run **7–10.5× faster**. See [Performance](./reference/performance.md).
|
|
28
|
+
|
|
29
|
+
Core pnext is pure Preact. `compat.react` runs React components and libraries on it, and `compat.next` runs a whole Next.js App Router app unchanged. Start anywhere on that ladder and move when it suits you. The App Router compatibility is validated against Next's own test suite (4,400+ assertions passing). The `pages/` folder is not supported, and neither are private internal utilities of Next.js or React. See [Compatibility](./reference/compat.md).
|
|
30
|
+
|
|
31
|
+
## A quick tour
|
|
32
|
+
|
|
33
|
+
### Your first page
|
|
34
|
+
|
|
35
|
+
Routes live in `app/`. A `page.tsx` is a Server Component by default. It runs only on the server, so it can be async and talk to your database, filesystem, or internal services directly. None of that code reaches the browser:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
// app/posts/[id]/page.tsx
|
|
39
|
+
import type { PageProps } from "#gen/app/posts/[id]/page";
|
|
40
|
+
|
|
41
|
+
export default async function Page({ params }: PageProps) {
|
|
42
|
+
const { id } = await params;
|
|
43
|
+
const post = await db.post.findUnique({ where: { id } });
|
|
44
|
+
return (
|
|
45
|
+
<article>
|
|
46
|
+
<h1>{post.title}</h1>
|
|
47
|
+
<p>{post.body}</p>
|
|
48
|
+
</article>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This page ships **0 KB** of JavaScript. Layouts work the same way: the root `layout.tsx` owns `<html>` and `<body>` and can export `metadata`.
|
|
54
|
+
|
|
55
|
+
### Adding interactivity
|
|
28
56
|
|
|
29
|
-
|
|
57
|
+
Mark a component with `"use client"` where you need state, effects, or event handlers. Server Components render it into the page, and only that island hydrates in the browser:
|
|
30
58
|
|
|
31
|
-
|
|
59
|
+
```tsx
|
|
60
|
+
// app/counter.tsx
|
|
61
|
+
"use client";
|
|
62
|
+
import { useState } from "preact/hooks";
|
|
32
63
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
64
|
+
export function Counter({ initial }: { initial: number }) {
|
|
65
|
+
const [count, setCount] = useState(initial);
|
|
66
|
+
return <button onClick={() => setCount(count + 1)}>Count {count}</button>;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Client Components hydrate on Preact for ~7.5 KB of framework, or ~12.5 KB with [`compat.react`](./reference/compat.md) if you want to run React components and libraries unchanged. Offscreen islands can stay out of the initial bundle entirely with `dynamic({ load: 'visible' })`.
|
|
71
|
+
|
|
72
|
+
### Streaming
|
|
73
|
+
|
|
74
|
+
Wrap slow server work in `<Suspense>`. The shell streams immediately and the content follows when it's ready:
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import { Suspense } from "@wular/pnext";
|
|
78
|
+
|
|
79
|
+
export default function Page() {
|
|
80
|
+
return (
|
|
81
|
+
<Suspense fallback={<p>Loading comments…</p>}>
|
|
82
|
+
<Comments />
|
|
83
|
+
</Suspense>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### APIs and everything else
|
|
89
|
+
|
|
90
|
+
A `route.ts` file is an HTTP handler:
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
// app/api/users/route.ts
|
|
94
|
+
export async function GET(request: NextRequest) {
|
|
95
|
+
return Response.json(await listUsers());
|
|
96
|
+
}
|
|
97
|
+
```
|
|
44
98
|
|
|
45
|
-
|
|
99
|
+
- `proxy.ts` runs before route matching.
|
|
100
|
+
- `loading.tsx`, `error.tsx`, and `not-found.tsx` define per-segment fallbacks.
|
|
101
|
+
- `pnext build` emits static HTML for routes that never read the request, and a server for the ones that do. `pnext start` serves it.
|
|
46
102
|
|
|
47
|
-
## Learn
|
|
103
|
+
## Learn more
|
|
48
104
|
|
|
49
105
|
Apps are file-routed from `app/`: `page.tsx` and `layout.tsx` are Server Components, `route.ts` files are HTTP handlers, `public/` is served from `/`. The reference covers the rest:
|
|
50
106
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wular/pnext",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"pnext": "bin/pnext"
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"./link": "./src/api/link.tsx",
|
|
24
24
|
"./navigation": "./src/api/navigation.ts",
|
|
25
25
|
"./navigation/client": "./src/api/client-navigation.ts",
|
|
26
|
-
"./server": "./src/api/server.ts"
|
|
26
|
+
"./server": "./src/api/server.ts",
|
|
27
|
+
"./config/*": "./config/*"
|
|
27
28
|
},
|
|
28
29
|
"scripts": {
|
|
29
30
|
"lint": "bun scripts/check-compat-boundary.ts && eslint . --max-warnings 0 && tsc --noEmit",
|
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
{
|
|
2
|
+
"run": {
|
|
3
|
+
"date": "2026-08-20",
|
|
4
|
+
"machine": "CI — Blacksmith 4 vCPU (Intel Xeon), 16 GB RAM, Ubuntu 22.04 x64",
|
|
5
|
+
"bun": "1.3.10",
|
|
6
|
+
"next": "16.2.12",
|
|
7
|
+
"runs": "5 per metric (first discarded), medians reported"
|
|
8
|
+
},
|
|
9
|
+
"fixtures": [
|
|
10
|
+
{
|
|
11
|
+
"id": "hello",
|
|
12
|
+
"label": "hello-world",
|
|
13
|
+
"blurb": "A single page."
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"id": "ssr",
|
|
17
|
+
"label": "ssr",
|
|
18
|
+
"blurb": "A server-rendered site."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "dashboard",
|
|
22
|
+
"label": "dashboard",
|
|
23
|
+
"blurb": "A mid-size admin app — 30 routes, 18 client islands."
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"metrics": [
|
|
27
|
+
{
|
|
28
|
+
"id": "dev-ready",
|
|
29
|
+
"label": "Dev server ready",
|
|
30
|
+
"category": "dev",
|
|
31
|
+
"phase": "cold",
|
|
32
|
+
"rows": {
|
|
33
|
+
"hello": [
|
|
34
|
+
56.4,
|
|
35
|
+
"56.4 ms",
|
|
36
|
+
212.3,
|
|
37
|
+
"212.3 ms",
|
|
38
|
+
3.76
|
|
39
|
+
],
|
|
40
|
+
"ssr": [
|
|
41
|
+
56,
|
|
42
|
+
"56.0 ms",
|
|
43
|
+
212.8,
|
|
44
|
+
"212.8 ms",
|
|
45
|
+
3.8
|
|
46
|
+
],
|
|
47
|
+
"dashboard": [
|
|
48
|
+
57.1,
|
|
49
|
+
"57.1 ms",
|
|
50
|
+
246.4,
|
|
51
|
+
"246.4 ms",
|
|
52
|
+
4.31
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "dev-first-page",
|
|
58
|
+
"label": "Dev first page HTML",
|
|
59
|
+
"category": "dev",
|
|
60
|
+
"phase": "cold",
|
|
61
|
+
"rows": {
|
|
62
|
+
"hello": [
|
|
63
|
+
79.9,
|
|
64
|
+
"79.9 ms",
|
|
65
|
+
993.5,
|
|
66
|
+
"993.5 ms",
|
|
67
|
+
12.44
|
|
68
|
+
],
|
|
69
|
+
"ssr": [
|
|
70
|
+
93.5,
|
|
71
|
+
"93.5 ms",
|
|
72
|
+
1043.3,
|
|
73
|
+
"1043.3 ms",
|
|
74
|
+
11.16
|
|
75
|
+
],
|
|
76
|
+
"dashboard": [
|
|
77
|
+
127,
|
|
78
|
+
"127.0 ms",
|
|
79
|
+
1285.8,
|
|
80
|
+
"1285.8 ms",
|
|
81
|
+
10.12
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"id": "dev-warm",
|
|
87
|
+
"label": "Dev warm request (p50 of 7)",
|
|
88
|
+
"category": "dev",
|
|
89
|
+
"phase": "warm",
|
|
90
|
+
"rows": {
|
|
91
|
+
"hello": [
|
|
92
|
+
3,
|
|
93
|
+
"3.0 ms",
|
|
94
|
+
14,
|
|
95
|
+
"14.0 ms",
|
|
96
|
+
4.69
|
|
97
|
+
],
|
|
98
|
+
"ssr": [
|
|
99
|
+
16.5,
|
|
100
|
+
"16.5 ms",
|
|
101
|
+
26.4,
|
|
102
|
+
"26.4 ms",
|
|
103
|
+
1.6
|
|
104
|
+
],
|
|
105
|
+
"dashboard": [
|
|
106
|
+
21.6,
|
|
107
|
+
"21.6 ms",
|
|
108
|
+
34.1,
|
|
109
|
+
"34.1 ms",
|
|
110
|
+
1.58
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": "hmr",
|
|
116
|
+
"label": "HMR save → visible",
|
|
117
|
+
"category": "dev",
|
|
118
|
+
"phase": "warm",
|
|
119
|
+
"rows": {
|
|
120
|
+
"hello": [
|
|
121
|
+
21.9,
|
|
122
|
+
"21.9 ms",
|
|
123
|
+
44.8,
|
|
124
|
+
"44.8 ms",
|
|
125
|
+
2.04
|
|
126
|
+
],
|
|
127
|
+
"ssr": [
|
|
128
|
+
264.3,
|
|
129
|
+
"264.3 ms",
|
|
130
|
+
68.3,
|
|
131
|
+
"68.3 ms",
|
|
132
|
+
0.26
|
|
133
|
+
],
|
|
134
|
+
"dashboard": [
|
|
135
|
+
300.4,
|
|
136
|
+
"300.4 ms",
|
|
137
|
+
97.6,
|
|
138
|
+
"97.6 ms",
|
|
139
|
+
0.32
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"id": "build-wall",
|
|
145
|
+
"label": "Production build (wall)",
|
|
146
|
+
"category": "build",
|
|
147
|
+
"phase": "cold",
|
|
148
|
+
"rows": {
|
|
149
|
+
"hello": [
|
|
150
|
+
291.3,
|
|
151
|
+
"291.3 ms",
|
|
152
|
+
2569.4,
|
|
153
|
+
"2569.4 ms",
|
|
154
|
+
8.82
|
|
155
|
+
],
|
|
156
|
+
"ssr": [
|
|
157
|
+
310.5,
|
|
158
|
+
"310.5 ms",
|
|
159
|
+
2738.8,
|
|
160
|
+
"2738.8 ms",
|
|
161
|
+
8.82
|
|
162
|
+
],
|
|
163
|
+
"dashboard": [
|
|
164
|
+
637.5,
|
|
165
|
+
"637.5 ms",
|
|
166
|
+
4566.3,
|
|
167
|
+
"4566.3 ms",
|
|
168
|
+
7.16
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"id": "prod-start",
|
|
174
|
+
"label": "Prod start (ready)",
|
|
175
|
+
"category": "build",
|
|
176
|
+
"phase": "cold",
|
|
177
|
+
"rows": {
|
|
178
|
+
"hello": [
|
|
179
|
+
60.7,
|
|
180
|
+
"60.7 ms",
|
|
181
|
+
110.9,
|
|
182
|
+
"110.9 ms",
|
|
183
|
+
1.83
|
|
184
|
+
],
|
|
185
|
+
"ssr": [
|
|
186
|
+
57.1,
|
|
187
|
+
"57.1 ms",
|
|
188
|
+
105.5,
|
|
189
|
+
"105.5 ms",
|
|
190
|
+
1.85
|
|
191
|
+
],
|
|
192
|
+
"dashboard": [
|
|
193
|
+
55.6,
|
|
194
|
+
"55.6 ms",
|
|
195
|
+
128.8,
|
|
196
|
+
"128.8 ms",
|
|
197
|
+
2.32
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"id": "prod-warm",
|
|
203
|
+
"label": "Prod warm request (p50 of 7)",
|
|
204
|
+
"category": "build",
|
|
205
|
+
"phase": "warm",
|
|
206
|
+
"rows": {
|
|
207
|
+
"hello": [
|
|
208
|
+
0.6,
|
|
209
|
+
"0.6 ms",
|
|
210
|
+
1.2,
|
|
211
|
+
"1.2 ms",
|
|
212
|
+
2.05
|
|
213
|
+
],
|
|
214
|
+
"ssr": [
|
|
215
|
+
0.5,
|
|
216
|
+
"0.5 ms",
|
|
217
|
+
1.3,
|
|
218
|
+
"1.3 ms",
|
|
219
|
+
2.5
|
|
220
|
+
],
|
|
221
|
+
"dashboard": [
|
|
222
|
+
0.5,
|
|
223
|
+
"0.5 ms",
|
|
224
|
+
1.7,
|
|
225
|
+
"1.7 ms",
|
|
226
|
+
3.41
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"id": "dev-rss",
|
|
232
|
+
"label": "Dev server RSS (ready + 7 warm)",
|
|
233
|
+
"category": "memory",
|
|
234
|
+
"phase": "warm",
|
|
235
|
+
"rows": {
|
|
236
|
+
"hello": [
|
|
237
|
+
130.8,
|
|
238
|
+
"130.8 MB",
|
|
239
|
+
536.4,
|
|
240
|
+
"536.4 MB",
|
|
241
|
+
4.1
|
|
242
|
+
],
|
|
243
|
+
"ssr": [
|
|
244
|
+
151.3,
|
|
245
|
+
"151.3 MB",
|
|
246
|
+
553.6,
|
|
247
|
+
"553.6 MB",
|
|
248
|
+
3.66
|
|
249
|
+
],
|
|
250
|
+
"dashboard": [
|
|
251
|
+
168.6,
|
|
252
|
+
"168.6 MB",
|
|
253
|
+
577.1,
|
|
254
|
+
"577.1 MB",
|
|
255
|
+
3.42
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"id": "build-rss",
|
|
261
|
+
"label": "Prod build peak RSS",
|
|
262
|
+
"category": "memory",
|
|
263
|
+
"phase": "cold",
|
|
264
|
+
"rows": {
|
|
265
|
+
"hello": [
|
|
266
|
+
124.2,
|
|
267
|
+
"124.2 MB",
|
|
268
|
+
455.8,
|
|
269
|
+
"455.8 MB",
|
|
270
|
+
3.67
|
|
271
|
+
],
|
|
272
|
+
"ssr": [
|
|
273
|
+
136.8,
|
|
274
|
+
"136.8 MB",
|
|
275
|
+
456.6,
|
|
276
|
+
"456.6 MB",
|
|
277
|
+
3.34
|
|
278
|
+
],
|
|
279
|
+
"dashboard": [
|
|
280
|
+
188,
|
|
281
|
+
"188.0 MB",
|
|
282
|
+
569,
|
|
283
|
+
"569.0 MB",
|
|
284
|
+
3.03
|
|
285
|
+
]
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
"id": "prod-rss",
|
|
290
|
+
"label": "Prod server RSS (ready + 7 warm)",
|
|
291
|
+
"category": "memory",
|
|
292
|
+
"phase": "warm",
|
|
293
|
+
"rows": {
|
|
294
|
+
"hello": [
|
|
295
|
+
85.2,
|
|
296
|
+
"85.2 MB",
|
|
297
|
+
85.7,
|
|
298
|
+
"85.7 MB",
|
|
299
|
+
1.01
|
|
300
|
+
],
|
|
301
|
+
"ssr": [
|
|
302
|
+
86,
|
|
303
|
+
"86.0 MB",
|
|
304
|
+
85.9,
|
|
305
|
+
"85.9 MB",
|
|
306
|
+
1
|
|
307
|
+
],
|
|
308
|
+
"dashboard": [
|
|
309
|
+
87.3,
|
|
310
|
+
"87.3 MB",
|
|
311
|
+
90.6,
|
|
312
|
+
"90.6 MB",
|
|
313
|
+
1.04
|
|
314
|
+
]
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"id": "install",
|
|
319
|
+
"label": "Framework install size",
|
|
320
|
+
"category": "payload",
|
|
321
|
+
"phase": "static",
|
|
322
|
+
"rows": {
|
|
323
|
+
"hello": [
|
|
324
|
+
7.1,
|
|
325
|
+
"7.1 MB",
|
|
326
|
+
420.7,
|
|
327
|
+
"420.7 MB",
|
|
328
|
+
59.14
|
|
329
|
+
],
|
|
330
|
+
"ssr": [
|
|
331
|
+
7.1,
|
|
332
|
+
"7.1 MB",
|
|
333
|
+
420.7,
|
|
334
|
+
"420.7 MB",
|
|
335
|
+
59.14
|
|
336
|
+
],
|
|
337
|
+
"dashboard": [
|
|
338
|
+
7.1,
|
|
339
|
+
"7.1 MB",
|
|
340
|
+
420.7,
|
|
341
|
+
"420.7 MB",
|
|
342
|
+
59.14
|
|
343
|
+
]
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
"id": "js-gzip",
|
|
348
|
+
"label": "First-page client JS (gzip)",
|
|
349
|
+
"category": "payload",
|
|
350
|
+
"phase": "static",
|
|
351
|
+
"rows": {
|
|
352
|
+
"hello": [
|
|
353
|
+
2.19,
|
|
354
|
+
"2.19 KB",
|
|
355
|
+
141.78,
|
|
356
|
+
"141.78 KB",
|
|
357
|
+
64.67
|
|
358
|
+
],
|
|
359
|
+
"ssr": [
|
|
360
|
+
11.39,
|
|
361
|
+
"11.39 KB",
|
|
362
|
+
142.03,
|
|
363
|
+
"142.03 KB",
|
|
364
|
+
12.47
|
|
365
|
+
],
|
|
366
|
+
"dashboard": [
|
|
367
|
+
15.26,
|
|
368
|
+
"15.26 KB",
|
|
369
|
+
144.85,
|
|
370
|
+
"144.85 KB",
|
|
371
|
+
9.5
|
|
372
|
+
]
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
"id": "js-raw",
|
|
377
|
+
"label": "First-page client JS (raw)",
|
|
378
|
+
"category": "payload",
|
|
379
|
+
"phase": "static",
|
|
380
|
+
"rows": {
|
|
381
|
+
"hello": [
|
|
382
|
+
4.43,
|
|
383
|
+
"4.43 KB",
|
|
384
|
+
502.47,
|
|
385
|
+
"502.47 KB",
|
|
386
|
+
113.36
|
|
387
|
+
],
|
|
388
|
+
"ssr": [
|
|
389
|
+
27.36,
|
|
390
|
+
"27.36 KB",
|
|
391
|
+
502.78,
|
|
392
|
+
"502.78 KB",
|
|
393
|
+
18.37
|
|
394
|
+
],
|
|
395
|
+
"dashboard": [
|
|
396
|
+
38.51,
|
|
397
|
+
"38.51 KB",
|
|
398
|
+
507.42,
|
|
399
|
+
"507.42 KB",
|
|
400
|
+
13.18
|
|
401
|
+
]
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"id": "js-files",
|
|
406
|
+
"label": "First-page JS files",
|
|
407
|
+
"category": "payload",
|
|
408
|
+
"phase": "static",
|
|
409
|
+
"rows": {
|
|
410
|
+
"hello": [
|
|
411
|
+
3,
|
|
412
|
+
"3",
|
|
413
|
+
5,
|
|
414
|
+
"5",
|
|
415
|
+
1.67
|
|
416
|
+
],
|
|
417
|
+
"ssr": [
|
|
418
|
+
4,
|
|
419
|
+
"4",
|
|
420
|
+
6,
|
|
421
|
+
"6",
|
|
422
|
+
1.5
|
|
423
|
+
],
|
|
424
|
+
"dashboard": [
|
|
425
|
+
6,
|
|
426
|
+
"6",
|
|
427
|
+
9,
|
|
428
|
+
"9",
|
|
429
|
+
1.5
|
|
430
|
+
]
|
|
431
|
+
}
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
"id": "zero-island",
|
|
435
|
+
"label": "Zero-island route client JS",
|
|
436
|
+
"category": "payload",
|
|
437
|
+
"phase": "static",
|
|
438
|
+
"rows": {
|
|
439
|
+
"hello": [
|
|
440
|
+
4.43,
|
|
441
|
+
"4.43 KB",
|
|
442
|
+
502.47,
|
|
443
|
+
"502.47 KB",
|
|
444
|
+
113.36
|
|
445
|
+
],
|
|
446
|
+
"ssr": [
|
|
447
|
+
4.46,
|
|
448
|
+
"4.46 KB",
|
|
449
|
+
502.47,
|
|
450
|
+
"502.47 KB",
|
|
451
|
+
112.56
|
|
452
|
+
]
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
],
|
|
456
|
+
"headlines": [
|
|
457
|
+
{
|
|
458
|
+
"label": "Dev server ready",
|
|
459
|
+
"direction": "faster",
|
|
460
|
+
"value": "3.8–4.3×"
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
"label": "First page, cold",
|
|
464
|
+
"direction": "faster",
|
|
465
|
+
"value": "10–12×"
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
"label": "Warm request (dev)",
|
|
469
|
+
"direction": "faster",
|
|
470
|
+
"value": "1.6–4.7×"
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
"label": "Production build",
|
|
474
|
+
"direction": "faster",
|
|
475
|
+
"value": "7.2–8.8×"
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
"label": "Warm request (prod)",
|
|
479
|
+
"direction": "faster",
|
|
480
|
+
"value": "2–3.4×"
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"label": "Dev server memory",
|
|
484
|
+
"direction": "less",
|
|
485
|
+
"value": "3.4–4.1×"
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
"label": "First-page client JS (gzip)",
|
|
489
|
+
"direction": "less",
|
|
490
|
+
"value": "9.5–65×"
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
"label": "Framework install size",
|
|
494
|
+
"direction": "smaller",
|
|
495
|
+
"value": "59×",
|
|
496
|
+
"detail": "7.1 MB vs 420.7 MB"
|
|
497
|
+
}
|
|
498
|
+
],
|
|
499
|
+
"clientRuntimes": [
|
|
500
|
+
{
|
|
501
|
+
"name": "router-prefetch-only",
|
|
502
|
+
"raw": "473 B",
|
|
503
|
+
"gzip": "348 B",
|
|
504
|
+
"brotli": "283 B"
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
"name": "combined-router-hydrator",
|
|
508
|
+
"raw": "10.47 KB",
|
|
509
|
+
"gzip": "4.47 KB",
|
|
510
|
+
"brotli": "4.07 KB"
|
|
511
|
+
}
|
|
512
|
+
]
|
|
513
|
+
}
|