one 1.2.39 → 1.2.41
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/dist/cjs/cli/build.cjs +18 -4
- package/dist/cjs/cli/build.js +21 -5
- package/dist/cjs/cli/build.js.map +1 -1
- package/dist/cjs/cli/build.native.js +31 -4
- package/dist/cjs/cli/build.native.js.map +1 -1
- package/dist/cjs/cli/buildPage.cjs +68 -14
- package/dist/cjs/cli/buildPage.js +65 -14
- package/dist/cjs/cli/buildPage.js.map +1 -1
- package/dist/cjs/cli/buildPage.native.js +86 -28
- package/dist/cjs/cli/buildPage.native.js.map +1 -1
- package/dist/cjs/constants.cjs +1 -0
- package/dist/cjs/constants.js +1 -0
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/constants.native.js +1 -0
- package/dist/cjs/constants.native.js.map +1 -1
- package/dist/cjs/createApp.cjs +2 -1
- package/dist/cjs/createApp.js +2 -1
- package/dist/cjs/createApp.js.map +1 -1
- package/dist/cjs/router/filterRootHTML.cjs +4 -4
- package/dist/cjs/router/filterRootHTML.js +4 -4
- package/dist/cjs/router/filterRootHTML.js.map +1 -1
- package/dist/cjs/router/filterRootHTML.native.js +7 -6
- package/dist/cjs/router/filterRootHTML.native.js.map +1 -1
- package/dist/cjs/router/useScreens.cjs +14 -5
- package/dist/cjs/router/useScreens.js +20 -3
- package/dist/cjs/router/useScreens.js.map +1 -1
- package/dist/cjs/router/useScreens.native.js +13 -4
- package/dist/cjs/router/useScreens.native.js.map +1 -1
- package/dist/cjs/server/ServerContextScript.cjs +12 -2
- package/dist/cjs/server/ServerContextScript.js +6 -2
- package/dist/cjs/server/ServerContextScript.js.map +1 -1
- package/dist/cjs/server/ServerContextScript.native.js +12 -2
- package/dist/cjs/server/ServerContextScript.native.js.map +1 -1
- package/dist/cjs/server/oneServe.cjs +3 -2
- package/dist/cjs/server/oneServe.js +4 -2
- package/dist/cjs/server/oneServe.js.map +2 -2
- package/dist/cjs/server/oneServe.native.js +3 -2
- package/dist/cjs/server/oneServe.native.js.map +1 -1
- package/dist/cjs/server-render.cjs +9 -1
- package/dist/cjs/server-render.js +9 -1
- package/dist/cjs/server-render.js.map +1 -1
- package/dist/cjs/server-render.native.js +12 -3
- package/dist/cjs/server-render.native.js.map +1 -1
- package/dist/cjs/vite/one.cjs +5 -1
- package/dist/cjs/vite/one.js +6 -3
- package/dist/cjs/vite/one.js.map +1 -1
- package/dist/cjs/vite/one.native.js +11 -2
- package/dist/cjs/vite/one.native.js.map +1 -1
- package/dist/esm/cli/build.js +21 -5
- package/dist/esm/cli/build.js.map +1 -1
- package/dist/esm/cli/build.mjs +18 -4
- package/dist/esm/cli/build.mjs.map +1 -1
- package/dist/esm/cli/build.native.js +31 -4
- package/dist/esm/cli/build.native.js.map +1 -1
- package/dist/esm/cli/buildPage.js +65 -14
- package/dist/esm/cli/buildPage.js.map +1 -1
- package/dist/esm/cli/buildPage.mjs +68 -14
- package/dist/esm/cli/buildPage.mjs.map +1 -1
- package/dist/esm/cli/buildPage.native.js +86 -28
- package/dist/esm/cli/buildPage.native.js.map +1 -1
- package/dist/esm/constants.js +1 -0
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/constants.mjs +1 -0
- package/dist/esm/constants.mjs.map +1 -1
- package/dist/esm/constants.native.js +1 -0
- package/dist/esm/constants.native.js.map +1 -1
- package/dist/esm/createApp.js +2 -1
- package/dist/esm/createApp.js.map +1 -1
- package/dist/esm/createApp.mjs +2 -1
- package/dist/esm/createApp.mjs.map +1 -1
- package/dist/esm/router/filterRootHTML.js +4 -4
- package/dist/esm/router/filterRootHTML.js.map +1 -1
- package/dist/esm/router/filterRootHTML.mjs +4 -4
- package/dist/esm/router/filterRootHTML.mjs.map +1 -1
- package/dist/esm/router/filterRootHTML.native.js +7 -6
- package/dist/esm/router/filterRootHTML.native.js.map +1 -1
- package/dist/esm/router/useScreens.js +20 -3
- package/dist/esm/router/useScreens.js.map +1 -1
- package/dist/esm/router/useScreens.mjs +14 -5
- package/dist/esm/router/useScreens.mjs.map +1 -1
- package/dist/esm/router/useScreens.native.js +13 -4
- package/dist/esm/router/useScreens.native.js.map +1 -1
- package/dist/esm/server/ServerContextScript.js +6 -2
- package/dist/esm/server/ServerContextScript.js.map +1 -1
- package/dist/esm/server/ServerContextScript.mjs +12 -2
- package/dist/esm/server/ServerContextScript.mjs.map +1 -1
- package/dist/esm/server/ServerContextScript.native.js +12 -2
- package/dist/esm/server/ServerContextScript.native.js.map +1 -1
- package/dist/esm/server/oneServe.js +4 -2
- package/dist/esm/server/oneServe.js.map +2 -2
- package/dist/esm/server/oneServe.mjs +3 -2
- package/dist/esm/server/oneServe.mjs.map +1 -1
- package/dist/esm/server/oneServe.native.js +3 -2
- package/dist/esm/server/oneServe.native.js.map +1 -1
- package/dist/esm/server-render.js +9 -1
- package/dist/esm/server-render.js.map +1 -1
- package/dist/esm/server-render.mjs +9 -1
- package/dist/esm/server-render.mjs.map +1 -1
- package/dist/esm/server-render.native.js +12 -3
- package/dist/esm/server-render.native.js.map +1 -1
- package/dist/esm/vite/one.js +6 -3
- package/dist/esm/vite/one.js.map +1 -1
- package/dist/esm/vite/one.mjs +5 -1
- package/dist/esm/vite/one.mjs.map +1 -1
- package/dist/esm/vite/one.native.js +11 -2
- package/dist/esm/vite/one.native.js.map +1 -1
- package/package.json +9 -9
- package/src/cli/build.ts +54 -6
- package/src/cli/buildPage.ts +104 -12
- package/src/constants.ts +1 -0
- package/src/createApp.tsx +1 -0
- package/src/router/filterRootHTML.ts +14 -15
- package/src/router/useScreens.tsx +27 -4
- package/src/server/ServerContextScript.tsx +13 -1
- package/src/server/oneServe.ts +3 -2
- package/src/server-render.tsx +29 -2
- package/src/types.ts +9 -0
- package/src/vite/one.ts +9 -3
- package/src/vite/types.ts +27 -0
- package/types/cli/build.d.ts.map +1 -1
- package/types/cli/buildPage.d.ts +1 -1
- package/types/cli/buildPage.d.ts.map +1 -1
- package/types/constants.d.ts.map +1 -1
- package/types/createApp.d.ts.map +1 -1
- package/types/router/filterRootHTML.d.ts.map +1 -1
- package/types/router/useScreens.d.ts.map +1 -1
- package/types/server/ServerContextScript.d.ts.map +1 -1
- package/types/server/oneServe.d.ts.map +1 -1
- package/types/server-render.d.ts +14 -2
- package/types/server-render.d.ts.map +1 -1
- package/types/types.d.ts +9 -0
- package/types/types.d.ts.map +1 -1
- package/types/vite/one.d.ts.map +1 -1
- package/types/vite/types.d.ts +26 -0
- package/types/vite/types.d.ts.map +1 -1
package/src/cli/buildPage.ts
CHANGED
|
@@ -23,7 +23,11 @@ export async function buildPage(
|
|
|
23
23
|
preloads: string[],
|
|
24
24
|
allCSS: string[],
|
|
25
25
|
routePreloads: Record<string, string>,
|
|
26
|
-
allCSSContents?: string[]
|
|
26
|
+
allCSSContents?: string[],
|
|
27
|
+
criticalPreloads?: string[],
|
|
28
|
+
deferredPreloads?: string[],
|
|
29
|
+
useAfterLCP?: boolean,
|
|
30
|
+
useAfterLCPAggressive?: boolean
|
|
27
31
|
): Promise<One.RouteBuildInfo> {
|
|
28
32
|
const render = await getRender(serverEntry)
|
|
29
33
|
const htmlPath = `${path.endsWith('/') ? `${removeTrailingSlash(path)}/index` : path}.html`
|
|
@@ -65,13 +69,19 @@ export async function buildPage(
|
|
|
65
69
|
await FSExtra.writeFile(join(clientDir, preloadPath), preloadContent)
|
|
66
70
|
|
|
67
71
|
// Generate CSS preload file with prefetch (on hover) and inject (on navigation) functions
|
|
72
|
+
// Deduplicate CSS URLs to avoid loading the same file multiple times
|
|
73
|
+
const uniqueCSS = [...new Set(allCSS)]
|
|
68
74
|
const cssPreloadContent = `
|
|
69
75
|
const CSS_TIMEOUT = 1000
|
|
70
|
-
const cssUrls = ${JSON.stringify(
|
|
76
|
+
const cssUrls = ${JSON.stringify(uniqueCSS)}
|
|
77
|
+
|
|
78
|
+
// Global cache for loaded CSS - avoids DOM queries and tracks across navigations
|
|
79
|
+
const loaded = (window.__oneLoadedCSS ||= new Set())
|
|
71
80
|
|
|
72
81
|
// Prefetch CSS without applying - called on link hover
|
|
73
82
|
export function prefetchCSS() {
|
|
74
83
|
cssUrls.forEach(href => {
|
|
84
|
+
if (loaded.has(href)) return
|
|
75
85
|
if (document.querySelector(\`link[href="\${href}"]\`)) return
|
|
76
86
|
const link = document.createElement('link')
|
|
77
87
|
link.rel = 'prefetch'
|
|
@@ -84,21 +94,31 @@ export function prefetchCSS() {
|
|
|
84
94
|
// Inject CSS to apply styles - called on actual navigation
|
|
85
95
|
export function injectCSS() {
|
|
86
96
|
return Promise.all(cssUrls.map(href => {
|
|
97
|
+
// Skip if already loaded
|
|
98
|
+
if (loaded.has(href)) return Promise.resolve()
|
|
87
99
|
// Remove any prefetch link for this href
|
|
88
100
|
const prefetchLink = document.querySelector(\`link[rel="prefetch"][href="\${href}"]\`)
|
|
89
101
|
if (prefetchLink) prefetchLink.remove()
|
|
90
|
-
// Skip if stylesheet already exists
|
|
91
|
-
if (document.querySelector(\`link[rel="stylesheet"][href="\${href}"]\`))
|
|
102
|
+
// Skip if stylesheet already exists in DOM
|
|
103
|
+
if (document.querySelector(\`link[rel="stylesheet"][href="\${href}"]\`)) {
|
|
104
|
+
loaded.add(href)
|
|
105
|
+
return Promise.resolve()
|
|
106
|
+
}
|
|
92
107
|
return new Promise(resolve => {
|
|
93
108
|
const link = document.createElement('link')
|
|
94
109
|
link.rel = 'stylesheet'
|
|
95
110
|
link.href = href
|
|
96
|
-
|
|
97
|
-
document.head.appendChild(link)
|
|
98
|
-
setTimeout(() => {
|
|
111
|
+
const timeoutId = setTimeout(() => {
|
|
99
112
|
console.warn('[one] CSS load timeout:', href)
|
|
113
|
+
loaded.add(href)
|
|
100
114
|
resolve()
|
|
101
115
|
}, CSS_TIMEOUT)
|
|
116
|
+
link.onload = link.onerror = () => {
|
|
117
|
+
clearTimeout(timeoutId)
|
|
118
|
+
loaded.add(href)
|
|
119
|
+
resolve()
|
|
120
|
+
}
|
|
121
|
+
document.head.appendChild(link)
|
|
102
122
|
})
|
|
103
123
|
}))
|
|
104
124
|
}
|
|
@@ -134,9 +154,16 @@ if (typeof document === 'undefined') globalThis.document = {}
|
|
|
134
154
|
globalThis['__vxrnresetState']?.()
|
|
135
155
|
|
|
136
156
|
if (foundRoute.type === 'ssg') {
|
|
137
|
-
|
|
157
|
+
// Aggressive mode: only modulepreload critical scripts, skip deferred to prevent network saturation
|
|
158
|
+
// Regular after-lcp mode: modulepreload all scripts for parallel downloads, defer execution
|
|
159
|
+
// Default: all scripts load normally
|
|
160
|
+
const renderPreloads = criticalPreloads || preloads
|
|
161
|
+
const renderDeferredPreloads = useAfterLCPAggressive ? [] : deferredPreloads
|
|
162
|
+
|
|
163
|
+
let html = await render({
|
|
138
164
|
path,
|
|
139
|
-
preloads,
|
|
165
|
+
preloads: renderPreloads,
|
|
166
|
+
deferredPreloads: renderDeferredPreloads,
|
|
140
167
|
loaderProps,
|
|
141
168
|
loaderData,
|
|
142
169
|
css: allCSS,
|
|
@@ -144,6 +171,13 @@ if (typeof document === 'undefined') globalThis.document = {}
|
|
|
144
171
|
mode: 'ssg',
|
|
145
172
|
routePreloads,
|
|
146
173
|
})
|
|
174
|
+
|
|
175
|
+
// Apply after-LCP script loading if enabled
|
|
176
|
+
// Load all preloads (not just critical) to ensure good TTI after first paint
|
|
177
|
+
if (useAfterLCP) {
|
|
178
|
+
html = applyAfterLCPScriptLoad(html, preloads)
|
|
179
|
+
}
|
|
180
|
+
|
|
147
181
|
await outputFile(htmlOutPath, html)
|
|
148
182
|
} else if (foundRoute.type === 'spa') {
|
|
149
183
|
// Generate CSS - either inline styles or link tags
|
|
@@ -154,13 +188,22 @@ if (typeof document === 'undefined') globalThis.document = {}
|
|
|
154
188
|
.join('\n')
|
|
155
189
|
: allCSS.map((file) => ` <link rel="stylesheet" href=${file} />`).join('\n')
|
|
156
190
|
|
|
191
|
+
// Use separated preloads if available
|
|
192
|
+
const criticalScripts = (criticalPreloads || preloads)
|
|
193
|
+
.map((preload) => ` <script type="module" src="${preload}"></script>`)
|
|
194
|
+
.join('\n')
|
|
195
|
+
|
|
196
|
+
// Non-critical scripts as modulepreload hints only
|
|
197
|
+
const deferredLinks = (deferredPreloads || [])
|
|
198
|
+
.map((preload) => ` <link rel="modulepreload" fetchPriority="low" href="${preload}"/>`)
|
|
199
|
+
.join('\n')
|
|
200
|
+
|
|
157
201
|
await outputFile(
|
|
158
202
|
htmlOutPath,
|
|
159
203
|
`<html><head>
|
|
160
204
|
${constants.getSpaHeaderElements({ serverContext: { loaderProps, loaderData } })}
|
|
161
|
-
${
|
|
162
|
-
|
|
163
|
-
.join('\n')}
|
|
205
|
+
${criticalScripts}
|
|
206
|
+
${deferredLinks}
|
|
164
207
|
${cssOutput}
|
|
165
208
|
</head></html>`
|
|
166
209
|
)
|
|
@@ -202,6 +245,8 @@ params:\n\n${JSON.stringify(params || null, null, 2)}`
|
|
|
202
245
|
params,
|
|
203
246
|
path,
|
|
204
247
|
preloads,
|
|
248
|
+
criticalPreloads,
|
|
249
|
+
deferredPreloads,
|
|
205
250
|
}
|
|
206
251
|
}
|
|
207
252
|
|
|
@@ -234,3 +279,50 @@ async function getRender(serverEntry: string) {
|
|
|
234
279
|
function removeTrailingSlash(path: string) {
|
|
235
280
|
return path.endsWith('/') ? path.slice(0, path.length - 1) : path
|
|
236
281
|
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Transforms HTML to delay script execution until after first paint.
|
|
285
|
+
* Keeps modulepreload links so critical scripts download in parallel.
|
|
286
|
+
* Removes async script tags and adds a loader that executes scripts after paint.
|
|
287
|
+
*/
|
|
288
|
+
function applyAfterLCPScriptLoad(html: string, preloads: string[]): string {
|
|
289
|
+
// Remove all <script type="module" ... async> tags (prevents immediate execution)
|
|
290
|
+
// Keep modulepreload links so critical scripts download in parallel
|
|
291
|
+
html = html.replace(/<script\s+type="module"[^>]*async[^>]*><\/script>/gi, '')
|
|
292
|
+
|
|
293
|
+
// Create the loader script
|
|
294
|
+
// Nested setTimeout yields to event loop multiple times, letting browser settle before loading scripts
|
|
295
|
+
const loaderScript = `
|
|
296
|
+
<script>
|
|
297
|
+
(function() {
|
|
298
|
+
var scripts = ${JSON.stringify(preloads)};
|
|
299
|
+
function loadScripts() {
|
|
300
|
+
scripts.forEach(function(src) {
|
|
301
|
+
var script = document.createElement('script');
|
|
302
|
+
script.type = 'module';
|
|
303
|
+
script.src = src;
|
|
304
|
+
document.head.appendChild(script);
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
function waitIdle(n) {
|
|
308
|
+
if (n <= 0) {
|
|
309
|
+
requestAnimationFrame(function() {
|
|
310
|
+
requestAnimationFrame(loadScripts);
|
|
311
|
+
});
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
setTimeout(function() {
|
|
315
|
+
setTimeout(function() {
|
|
316
|
+
waitIdle(n - 1);
|
|
317
|
+
}, 0);
|
|
318
|
+
}, 0);
|
|
319
|
+
}
|
|
320
|
+
waitIdle(5);
|
|
321
|
+
})();
|
|
322
|
+
</script>`
|
|
323
|
+
|
|
324
|
+
// Insert the loader script before </head>
|
|
325
|
+
html = html.replace('</head>', `${loaderScript}</head>`)
|
|
326
|
+
|
|
327
|
+
return html
|
|
328
|
+
}
|
package/src/constants.ts
CHANGED
|
@@ -28,4 +28,5 @@ export const getSpaHeaderElements = ({
|
|
|
28
28
|
<script>globalThis['global'] = globalThis</script>
|
|
29
29
|
<script>globalThis['__vxrnIsSPA'] = true</script>
|
|
30
30
|
<script>globalThis["${SERVER_CONTEXT_KEY}"] = ${JSON.stringify(serverContext)}</script>
|
|
31
|
+
<script>globalThis.__oneLoadedCSS = new Set(${JSON.stringify(serverContext.css || [])})</script>
|
|
31
32
|
`
|
package/src/createApp.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isValidElement } from 'react'
|
|
2
2
|
|
|
3
3
|
type Props = Record<string, any>
|
|
4
4
|
|
|
@@ -36,12 +36,8 @@ export function filterRootHTML(el: React.ReactNode): FoundRootHTML {
|
|
|
36
36
|
const { type, props } = reactElement
|
|
37
37
|
|
|
38
38
|
if (type === 'html') {
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
typeof reactElement.props === 'object' &&
|
|
42
|
-
'children' in reactElement.props
|
|
43
|
-
) {
|
|
44
|
-
const { children, ...restProps } = reactElement.props
|
|
39
|
+
if (props && typeof props === 'object' && 'children' in props) {
|
|
40
|
+
const { children, ...restProps } = props
|
|
45
41
|
htmlProps = restProps
|
|
46
42
|
return traverse(children as React.ReactNode)
|
|
47
43
|
}
|
|
@@ -54,13 +50,13 @@ export function filterRootHTML(el: React.ReactNode): FoundRootHTML {
|
|
|
54
50
|
}
|
|
55
51
|
|
|
56
52
|
if (type === 'body') {
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
typeof reactElement.props === 'object' &&
|
|
60
|
-
'children' in reactElement.props
|
|
61
|
-
) {
|
|
62
|
-
const { children, ...restProps } = reactElement.props
|
|
53
|
+
if (props && typeof props === 'object' && 'children' in props) {
|
|
54
|
+
const { children, ...restProps } = props
|
|
63
55
|
bodyProps = restProps
|
|
56
|
+
if (process.env.TAMAGUI_TARGET === 'native') {
|
|
57
|
+
// must traverse children so nested HTML elements (e.g. <div>) get filtered on native
|
|
58
|
+
return traverse(children as React.ReactNode)
|
|
59
|
+
}
|
|
64
60
|
return children as React.ReactNode
|
|
65
61
|
}
|
|
66
62
|
return null
|
|
@@ -72,8 +68,11 @@ export function filterRootHTML(el: React.ReactNode): FoundRootHTML {
|
|
|
72
68
|
typeof element.type === 'string' &&
|
|
73
69
|
element.type.toLowerCase() === element.type
|
|
74
70
|
) {
|
|
75
|
-
// filter out
|
|
76
|
-
//
|
|
71
|
+
// filter out HTML elements on native (e.g. <div>, <meta>)
|
|
72
|
+
// preserve children so <div><Slot/></div> renders <Slot/> instead of nothing
|
|
73
|
+
if (element.props && typeof element.props === 'object' && 'children' in element.props) {
|
|
74
|
+
return traverse(element.props.children as React.ReactNode)
|
|
75
|
+
}
|
|
77
76
|
return null
|
|
78
77
|
}
|
|
79
78
|
}
|
|
@@ -29,6 +29,22 @@ import { sortRoutesWithInitial } from './sortRoutes'
|
|
|
29
29
|
// do this hack.
|
|
30
30
|
export const { Screen, Group } = createNavigatorFactory({} as any)()
|
|
31
31
|
|
|
32
|
+
// Cache inline CSS elements at module load (before React hydrates).
|
|
33
|
+
// Reads CSS content from SSR'd <style> elements and creates matching JSX
|
|
34
|
+
// so hydration sees identical content without 100KB+ JSON payload.
|
|
35
|
+
const cachedInlineCSSElements: React.ReactNode[] =
|
|
36
|
+
typeof document !== 'undefined'
|
|
37
|
+
? Array.from(document.querySelectorAll<HTMLStyleElement>('style[id^="__one_css_"]')).map(
|
|
38
|
+
(el, i) => (
|
|
39
|
+
<style
|
|
40
|
+
key={`inline-css-${i}`}
|
|
41
|
+
id={el.id}
|
|
42
|
+
dangerouslySetInnerHTML={{ __html: el.innerHTML }}
|
|
43
|
+
/>
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
: []
|
|
47
|
+
|
|
32
48
|
export type ScreenProps<
|
|
33
49
|
TOptions extends Record<string, any> = Record<string, any>,
|
|
34
50
|
State extends NavigationState = NavigationState,
|
|
@@ -205,10 +221,17 @@ export function getQualifiedRouteComponent(value: RouteNode) {
|
|
|
205
221
|
__html: `globalThis['global'] = globalThis`,
|
|
206
222
|
}}
|
|
207
223
|
/>
|
|
208
|
-
{serverContext?.cssContents
|
|
209
|
-
?
|
|
210
|
-
|
|
211
|
-
)
|
|
224
|
+
{serverContext?.cssContents?.length || serverContext?.cssInlineCount
|
|
225
|
+
? // Inline CSS: SSR renders fresh, client uses cached elements from module load
|
|
226
|
+
serverContext?.cssContents
|
|
227
|
+
? serverContext.cssContents.map((content, i) => (
|
|
228
|
+
<style
|
|
229
|
+
key={`inline-css-${i}`}
|
|
230
|
+
id={`__one_css_${i}`}
|
|
231
|
+
dangerouslySetInnerHTML={{ __html: content }}
|
|
232
|
+
/>
|
|
233
|
+
))
|
|
234
|
+
: cachedInlineCSSElements
|
|
212
235
|
: serverContext?.css?.map((file) => <link key={file} rel="stylesheet" href={file} />)}
|
|
213
236
|
<ServerContextScript />
|
|
214
237
|
{headChildren}
|
|
@@ -19,6 +19,17 @@ export function ServerContextScript() {
|
|
|
19
19
|
|
|
20
20
|
if (process.env.VITE_ENVIRONMENT === 'ssr') {
|
|
21
21
|
const context = useServerContext()
|
|
22
|
+
const cssUrls = context?.css || []
|
|
23
|
+
|
|
24
|
+
// Strip cssContents from JSON payload - we'll read it from DOM instead.
|
|
25
|
+
// This avoids duplicating 100KB+ of CSS as JSON in the HTML.
|
|
26
|
+
// The CSSPrehydrateScript reads the actual <style> elements' innerHTML
|
|
27
|
+
// and stores them in globalThis.__oneCSSContents for hydration matching.
|
|
28
|
+
const { cssContents, ...restContext } = context || {}
|
|
29
|
+
const clientContext = {
|
|
30
|
+
...restContext,
|
|
31
|
+
cssInlineCount: cssContents?.length || 0,
|
|
32
|
+
}
|
|
22
33
|
|
|
23
34
|
return (
|
|
24
35
|
<script
|
|
@@ -29,9 +40,10 @@ export function ServerContextScript() {
|
|
|
29
40
|
dangerouslySetInnerHTML={{
|
|
30
41
|
__html: `
|
|
31
42
|
globalThis["${SERVER_CONTEXT_KEY}"] = ${JSON.stringify({
|
|
32
|
-
...
|
|
43
|
+
...clientContext,
|
|
33
44
|
postRenderData: SERVER_CONTEXT_POST_RENDER_STRING,
|
|
34
45
|
})};
|
|
46
|
+
globalThis.__oneLoadedCSS = new Set(${JSON.stringify(cssUrls)});
|
|
35
47
|
`,
|
|
36
48
|
}}
|
|
37
49
|
/>
|
package/src/server/oneServe.ts
CHANGED
|
@@ -111,7 +111,6 @@ export async function oneServe(oneOptions: One.PluginOptions, buildInfo: One.Bui
|
|
|
111
111
|
try {
|
|
112
112
|
const exported = await import(toAbsolute(buildInfo.serverJsPath))
|
|
113
113
|
const loaderData = await exported.loader?.(loaderProps)
|
|
114
|
-
const preloads = buildInfo.preloads
|
|
115
114
|
|
|
116
115
|
const headers = new Headers()
|
|
117
116
|
headers.set('content-type', 'text/html')
|
|
@@ -121,7 +120,9 @@ export async function oneServe(oneOptions: One.PluginOptions, buildInfo: One.Bui
|
|
|
121
120
|
loaderData,
|
|
122
121
|
loaderProps,
|
|
123
122
|
path: loaderProps?.path || '/',
|
|
124
|
-
preloads
|
|
123
|
+
// Use separated preloads for optimal loading
|
|
124
|
+
preloads: buildInfo.criticalPreloads || buildInfo.preloads,
|
|
125
|
+
deferredPreloads: buildInfo.deferredPreloads,
|
|
125
126
|
css: buildInfo.css,
|
|
126
127
|
cssContents: buildInfo.cssContents,
|
|
127
128
|
})
|
package/src/server-render.tsx
CHANGED
|
@@ -1,11 +1,38 @@
|
|
|
1
1
|
import ReactDOMServer from 'react-dom/server.browser'
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export type RenderToStringOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* Critical scripts that need to execute immediately (will use async).
|
|
6
|
+
* These are added to bootstrapModules and generate both modulepreload links and async script tags.
|
|
7
|
+
* Keep this list minimal (typically: setupClient, one-entry, page entry).
|
|
8
|
+
*/
|
|
9
|
+
preloads?: string[]
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Non-critical scripts that can wait (will only be modulepreload hints).
|
|
13
|
+
* These only generate <link rel="modulepreload"> tags and are loaded when imported.
|
|
14
|
+
* Use this for component libraries, utilities, and other non-essential modules.
|
|
15
|
+
*/
|
|
16
|
+
deferredPreloads?: string[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const renderToString = async (app: React.ReactElement, options: RenderToStringOptions) => {
|
|
4
20
|
const readableStream = await ReactDOMServer.renderToReadableStream(app, {
|
|
21
|
+
// Only pass critical scripts to bootstrapModules
|
|
22
|
+
// These generate both modulepreload links AND async script tags
|
|
5
23
|
bootstrapModules: options.preloads,
|
|
6
24
|
})
|
|
7
25
|
await readableStream.allReady
|
|
8
|
-
|
|
26
|
+
let out = await streamToString(readableStream)
|
|
27
|
+
|
|
28
|
+
// Add non-critical modulepreload links to head (just hints, no script execution)
|
|
29
|
+
if (options.deferredPreloads?.length) {
|
|
30
|
+
const modulepreloadLinks = options.deferredPreloads
|
|
31
|
+
.map((src) => `<link rel="modulepreload" fetchPriority="low" href="${src}"/>`)
|
|
32
|
+
.join('')
|
|
33
|
+
out = out.replace('</head>', `${modulepreloadLinks}</head>`)
|
|
34
|
+
}
|
|
35
|
+
|
|
9
36
|
return out
|
|
10
37
|
}
|
|
11
38
|
|
package/src/types.ts
CHANGED
|
@@ -19,7 +19,16 @@ export type LoaderProps<Params extends Object = Record<string, string | string[]
|
|
|
19
19
|
export type RenderAppProps = {
|
|
20
20
|
mode: One.RouteRenderMode
|
|
21
21
|
path: string
|
|
22
|
+
/**
|
|
23
|
+
* Critical scripts that need to execute immediately (will use async).
|
|
24
|
+
* These generate both modulepreload links and async script tags.
|
|
25
|
+
*/
|
|
22
26
|
preloads?: string[]
|
|
27
|
+
/**
|
|
28
|
+
* Non-critical scripts that can wait (will only be modulepreload hints).
|
|
29
|
+
* These only generate <link rel="modulepreload"> tags and load when imported.
|
|
30
|
+
*/
|
|
31
|
+
deferredPreloads?: string[]
|
|
23
32
|
css?: string[]
|
|
24
33
|
/** When inlineLayoutCSS is enabled, this contains the actual CSS content to inline */
|
|
25
34
|
cssContents?: string[]
|
package/src/vite/one.ts
CHANGED
|
@@ -204,9 +204,15 @@ export function one(options: One.PluginOptions = {}): PluginOption {
|
|
|
204
204
|
return
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
207
|
+
const skipDotDirs = (dir: string) => {
|
|
208
|
+
const name = dir.split('/').pop() || ''
|
|
209
|
+
return name.startsWith('.')
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
tsConfigPathsPlugin = tsconfigPaths({
|
|
213
|
+
skip: skipDotDirs,
|
|
214
|
+
...(pathsConfig && typeof pathsConfig === 'object' ? pathsConfig : {}),
|
|
215
|
+
})
|
|
210
216
|
},
|
|
211
217
|
|
|
212
218
|
configResolved() {},
|
package/src/vite/types.ts
CHANGED
|
@@ -344,6 +344,26 @@ export namespace One {
|
|
|
344
344
|
*/
|
|
345
345
|
inlineLayoutCSS?: boolean
|
|
346
346
|
|
|
347
|
+
/**
|
|
348
|
+
* @experimental
|
|
349
|
+
* Controls how scripts are loaded for improved performance.
|
|
350
|
+
*
|
|
351
|
+
* - `'defer-non-critical'`: Critical scripts (framework entry, page, layouts) load immediately.
|
|
352
|
+
* Non-critical scripts (component imports, utilities) become modulepreload hints only,
|
|
353
|
+
* reducing network/CPU contention.
|
|
354
|
+
*
|
|
355
|
+
* - `'after-lcp'`: Scripts download immediately via modulepreload but execution is deferred
|
|
356
|
+
* until after first paint using double requestAnimationFrame. This allows the browser to
|
|
357
|
+
* paint the SSR content before executing JavaScript. Only applies to SSG pages.
|
|
358
|
+
*
|
|
359
|
+
* - `'after-lcp-aggressive'`: Only modulepreloads critical scripts (entry, layouts).
|
|
360
|
+
* Non-critical scripts have no modulepreload hints, reducing network saturation.
|
|
361
|
+
* Best for pages with many chunks or slow networks.
|
|
362
|
+
*
|
|
363
|
+
* @default undefined (all scripts load with async)
|
|
364
|
+
*/
|
|
365
|
+
experimental_scriptLoading?: 'defer-non-critical' | 'after-lcp' | 'after-lcp-aggressive'
|
|
366
|
+
|
|
347
367
|
/**
|
|
348
368
|
* Generate a sitemap.xml file during build.
|
|
349
369
|
*
|
|
@@ -445,7 +465,12 @@ export namespace One {
|
|
|
445
465
|
serverJsPath: string
|
|
446
466
|
params: Object
|
|
447
467
|
loaderData: any
|
|
468
|
+
/** All preloads (for backwards compatibility) */
|
|
448
469
|
preloads: string[]
|
|
470
|
+
/** Critical preloads that load immediately with async */
|
|
471
|
+
criticalPreloads?: string[]
|
|
472
|
+
/** Non-critical preloads that are modulepreload hints only */
|
|
473
|
+
deferredPreloads?: string[]
|
|
449
474
|
css: string[]
|
|
450
475
|
/** When inlineLayoutCSS is enabled, contains the actual CSS content */
|
|
451
476
|
cssContents?: string[]
|
|
@@ -455,6 +480,8 @@ export namespace One {
|
|
|
455
480
|
css?: string[]
|
|
456
481
|
/** When inlineLayoutCSS is enabled, this contains the actual CSS content to inline */
|
|
457
482
|
cssContents?: string[]
|
|
483
|
+
/** Number of inline CSS entries - used for hydration matching when cssContents is stripped */
|
|
484
|
+
cssInlineCount?: number
|
|
458
485
|
postRenderData?: any
|
|
459
486
|
loaderData?: any
|
|
460
487
|
loaderProps?: any
|
package/types/cli/build.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAoCA,wBAAsB,KAAK,CAAC,IAAI,EAAE;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAAA;CACrC,
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAoCA,wBAAsB,KAAK,CAAC,IAAI,EAAE;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAAA;CACrC,iBAqpBA"}
|
package/types/cli/buildPage.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { One, RouteInfo } from '../vite/types';
|
|
2
|
-
export declare function buildPage(serverEntry: string, path: string, relativeId: string, params: any, foundRoute: RouteInfo<string>, clientManifestEntry: any, staticDir: string, clientDir: string, builtMiddlewares: Record<string, string>, serverJsPath: string, preloads: string[], allCSS: string[], routePreloads: Record<string, string>, allCSSContents?: string[]): Promise<One.RouteBuildInfo>;
|
|
2
|
+
export declare function buildPage(serverEntry: string, path: string, relativeId: string, params: any, foundRoute: RouteInfo<string>, clientManifestEntry: any, staticDir: string, clientDir: string, builtMiddlewares: Record<string, string>, serverJsPath: string, preloads: string[], allCSS: string[], routePreloads: Record<string, string>, allCSSContents?: string[], criticalPreloads?: string[], deferredPreloads?: string[], useAfterLCP?: boolean, useAfterLCPAggressive?: boolean): Promise<One.RouteBuildInfo>;
|
|
3
3
|
//# sourceMappingURL=buildPage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildPage.d.ts","sourceRoot":"","sources":["../../src/cli/buildPage.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAInD,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,GAAG,EACX,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,EAC7B,mBAAmB,EAAE,GAAG,EACxB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACxC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAAE,EAClB,MAAM,EAAE,MAAM,EAAE,EAChB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,cAAc,CAAC,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"buildPage.d.ts","sourceRoot":"","sources":["../../src/cli/buildPage.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAInD,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,GAAG,EACX,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,EAC7B,mBAAmB,EAAE,GAAG,EACxB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACxC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAAE,EAClB,MAAM,EAAE,MAAM,EAAE,EAChB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,cAAc,CAAC,EAAE,MAAM,EAAE,EACzB,gBAAgB,CAAC,EAAE,MAAM,EAAE,EAC3B,gBAAgB,CAAC,EAAE,MAAM,EAAE,EAC3B,WAAW,CAAC,EAAE,OAAO,EACrB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CA4N7B"}
|
package/types/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAEvC,eAAO,MAAM,WAAW,SAA2E,CAAA;AACnG,eAAO,MAAM,WAAW,SAA2E,CAAA;AACnG,eAAO,MAAM,QAAQ,SAA0C,CAAA;AAE/D,eAAO,MAAM,SAAS,QAA4E,CAAA;AAElG,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAC3D,eAAO,MAAM,8BAA8B,0BAAwC,CAAA;AACnF,eAAO,MAAM,uBAAuB,QAA6C,CAAA;AACjF,eAAO,MAAM,iBAAiB,QAA+C,CAAA;AAE7E,eAAO,MAAM,kBAAkB,QAA6B,CAAA;AAC5D,eAAO,MAAM,sBAAsB,QAAiC,CAAA;AAGpE,eAAO,MAAM,qBAAqB,wBAAwB,CAAA;AAC1D,eAAO,MAAM,oBAAoB,oCAAyC,CAAA;AAE1E,eAAO,MAAM,kBAAkB,2BAA2B,CAAA;AAE1D,eAAO,MAAM,oBAAoB,GAAI,qBAElC;IACD,aAAa,CAAC,EAAE,GAAG,CAAC,aAAa,CAAA;CAC7B,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAEvC,eAAO,MAAM,WAAW,SAA2E,CAAA;AACnG,eAAO,MAAM,WAAW,SAA2E,CAAA;AACnG,eAAO,MAAM,QAAQ,SAA0C,CAAA;AAE/D,eAAO,MAAM,SAAS,QAA4E,CAAA;AAElG,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAC3D,eAAO,MAAM,8BAA8B,0BAAwC,CAAA;AACnF,eAAO,MAAM,uBAAuB,QAA6C,CAAA;AACjF,eAAO,MAAM,iBAAiB,QAA+C,CAAA;AAE7E,eAAO,MAAM,kBAAkB,QAA6B,CAAA;AAC5D,eAAO,MAAM,sBAAsB,QAAiC,CAAA;AAGpE,eAAO,MAAM,qBAAqB,wBAAwB,CAAA;AAC1D,eAAO,MAAM,oBAAoB,oCAAyC,CAAA;AAE1E,eAAO,MAAM,kBAAkB,2BAA2B,CAAA;AAE1D,eAAO,MAAM,oBAAoB,GAAI,qBAElC;IACD,aAAa,CAAC,EAAE,GAAG,CAAC,aAAa,CAAA;CAC7B,WAKL,CAAA"}
|
package/types/createApp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createApp.d.ts","sourceRoot":"","sources":["../src/createApp.tsx"],"names":[],"mappings":"AAAA,OAAO,SAAS,CAAA;AAQhB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAK7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAEvC,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;IAC9C,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC,KAAK,CAAA;CAClB,CAAA;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,cAAc;;oBAIrB,cAAc;
|
|
1
|
+
{"version":3,"file":"createApp.d.ts","sourceRoot":"","sources":["../src/createApp.tsx"],"names":[],"mappings":"AAAA,OAAO,SAAS,CAAA;AAQhB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAK7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAEvC,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;IAC9C,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC,KAAK,CAAA;CAClB,CAAA;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,cAAc;;oBAIrB,cAAc;EAyIzC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterRootHTML.d.ts","sourceRoot":"","sources":["../../src/router/filterRootHTML.ts"],"names":[],"mappings":"AAEA,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAEhC,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAA;IAC5B,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB,IAAI,CAAC,EAAE,KAAK,CAAC,YAAY,CAAA;CAC1B,CAAA;AAED;;;;;;;;GAQG;AAEH,wBAAgB,cAAc,CAAC,EAAE,EAAE,KAAK,CAAC,SAAS,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"filterRootHTML.d.ts","sourceRoot":"","sources":["../../src/router/filterRootHTML.ts"],"names":[],"mappings":"AAEA,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAEhC,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAA;IAC5B,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB,SAAS,CAAC,EAAE,KAAK,CAAA;IACjB,IAAI,CAAC,EAAE,KAAK,CAAC,YAAY,CAAA;CAC1B,CAAA;AAED;;;;;;;;GAQG;AAEH,wBAAgB,cAAc,CAAC,EAAE,EAAE,KAAK,CAAC,SAAS,GAAG,aAAa,CAwEjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useScreens.d.ts","sourceRoot":"","sources":["../../src/router/useScreens.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,SAAS,EACT,eAAe,EAChB,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAAgC,MAAM,OAAO,CAAA;AASpD,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,SAAS,CAAA;AAKhB,eAAO,MAAQ,MAAM,OAAE,KAAK,KAAwC,CAAA;
|
|
1
|
+
{"version":3,"file":"useScreens.d.ts","sourceRoot":"","sources":["../../src/router/useScreens.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,SAAS,EACT,eAAe,EAChB,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAAgC,MAAM,OAAO,CAAA;AASpD,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,SAAS,CAAA;AAKhB,eAAO,MAAQ,MAAM,OAAE,KAAK,KAAwC,CAAA;AAkBpE,MAAM,MAAM,WAAW,CACrB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1D,KAAK,SAAS,eAAe,GAAG,eAAe,EAC/C,QAAQ,SAAS,YAAY,GAAG,YAAY,IAC1C;IACF,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACnC,OAAO,CAAC,EAAE,QAAQ,CAAA;IAElB,SAAS,CAAC,EACN,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,GAChC,CAAC,CAAC,IAAI,EAAE;QACN,KAAK,EAAE,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;QACvC,UAAU,EAAE,GAAG,CAAA;KAChB,KAAK,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAA;IAE3C,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,KAAK,MAAM,GAAG,SAAS,CAAA;CAC7E,CAAA;AAgED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,WAAW,EAAE,EACpB,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GACnC,KAAK,CAAC,SAAS,EAAE,CAYnB;AA4BD,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,SAAS,0GAgI1D;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,GAAG,YAAY,GAAG,UAAU,CAAC,IAU/D;aAAmC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAAE,YAoBjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerContextScript.d.ts","sourceRoot":"","sources":["../../src/server/ServerContextScript.tsx"],"names":[],"mappings":"AAIA,wBAAgB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"ServerContextScript.d.ts","sourceRoot":"","sources":["../../src/server/ServerContextScript.tsx"],"names":[],"mappings":"AAIA,wBAAgB,mBAAmB,mDAiDlC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oneServe.d.ts","sourceRoot":"","sources":["../../src/server/oneServe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAqB,MAAM,MAAM,CAAA;AAoBnD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAA;AAKxC,wBAAsB,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,aAAa,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"oneServe.d.ts","sourceRoot":"","sources":["../../src/server/oneServe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAqB,MAAM,MAAM,CAAA;AAoBnD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAA;AAKxC,wBAAsB,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,aAAa,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,iBAgUhG"}
|
package/types/server-render.d.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type RenderToStringOptions = {
|
|
2
|
+
/**
|
|
3
|
+
* Critical scripts that need to execute immediately (will use async).
|
|
4
|
+
* These are added to bootstrapModules and generate both modulepreload links and async script tags.
|
|
5
|
+
* Keep this list minimal (typically: setupClient, one-entry, page entry).
|
|
6
|
+
*/
|
|
2
7
|
preloads?: string[];
|
|
3
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Non-critical scripts that can wait (will only be modulepreload hints).
|
|
10
|
+
* These only generate <link rel="modulepreload"> tags and are loaded when imported.
|
|
11
|
+
* Use this for component libraries, utilities, and other non-essential modules.
|
|
12
|
+
*/
|
|
13
|
+
deferredPreloads?: string[];
|
|
14
|
+
};
|
|
15
|
+
export declare const renderToString: (app: React.ReactElement, options: RenderToStringOptions) => Promise<string>;
|
|
4
16
|
//# sourceMappingURL=server-render.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-render.d.ts","sourceRoot":"","sources":["../src/server-render.tsx"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"server-render.d.ts","sourceRoot":"","sources":["../src/server-render.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IAEnB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC5B,CAAA;AAED,eAAO,MAAM,cAAc,GAAU,KAAK,KAAK,CAAC,YAAY,EAAE,SAAS,qBAAqB,oBAkB3F,CAAA"}
|
package/types/types.d.ts
CHANGED
|
@@ -13,7 +13,16 @@ export type LoaderProps<Params extends Object = Record<string, string | string[]
|
|
|
13
13
|
export type RenderAppProps = {
|
|
14
14
|
mode: One.RouteRenderMode;
|
|
15
15
|
path: string;
|
|
16
|
+
/**
|
|
17
|
+
* Critical scripts that need to execute immediately (will use async).
|
|
18
|
+
* These generate both modulepreload links and async script tags.
|
|
19
|
+
*/
|
|
16
20
|
preloads?: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Non-critical scripts that can wait (will only be modulepreload hints).
|
|
23
|
+
* These only generate <link rel="modulepreload"> tags and load when imported.
|
|
24
|
+
*/
|
|
25
|
+
deferredPreloads?: string[];
|
|
17
26
|
css?: string[];
|
|
18
27
|
/** When inlineLayoutCSS is enabled, this contains the actual CSS content to inline */
|
|
19
28
|
cssContents?: string[];
|
package/types/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAEvC,yFAAyF;AACzF,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AAEhF,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;AAExE,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAE1E,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAElE,MAAM,MAAM,WAAW,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI;IACnF,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,GAAG,CAAC,eAAe,CAAA;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAA;IACd,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,gBAAgB,CAAC,EAAE,GAAG,CAAA;IACtB,UAAU,CAAC,EAAE,GAAG,CAAA;IAChB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACvC,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAEvC,yFAAyF;AACzF,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AAEhF,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;AAExE,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAE1E,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAElE,MAAM,MAAM,WAAW,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI;IACnF,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,GAAG,CAAC,eAAe,CAAA;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,GAAG,CAAC,EAAE,MAAM,EAAE,CAAA;IACd,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,gBAAgB,CAAC,EAAE,GAAG,CAAA;IACtB,UAAU,CAAC,EAAE,GAAG,CAAA;IAChB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACvC,CAAA"}
|
package/types/vite/one.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"one.d.ts","sourceRoot":"","sources":["../../src/vite/one.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAU,YAAY,EAAE,MAAM,MAAM,CAAA;AAOhD,OAAO,qBAAqB,CAAA;AAW5B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AAoBlC,wBAAgB,GAAG,CAAC,OAAO,GAAE,GAAG,CAAC,aAAkB,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"one.d.ts","sourceRoot":"","sources":["../../src/vite/one.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAU,YAAY,EAAE,MAAM,MAAM,CAAA;AAOhD,OAAO,qBAAqB,CAAA;AAW5B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AAoBlC,wBAAgB,GAAG,CAAC,OAAO,GAAE,GAAG,CAAC,aAAkB,GAAG,YAAY,CAokBjE"}
|
package/types/vite/types.d.ts
CHANGED
|
@@ -300,6 +300,25 @@ export declare namespace One {
|
|
|
300
300
|
* @default false
|
|
301
301
|
*/
|
|
302
302
|
inlineLayoutCSS?: boolean;
|
|
303
|
+
/**
|
|
304
|
+
* @experimental
|
|
305
|
+
* Controls how scripts are loaded for improved performance.
|
|
306
|
+
*
|
|
307
|
+
* - `'defer-non-critical'`: Critical scripts (framework entry, page, layouts) load immediately.
|
|
308
|
+
* Non-critical scripts (component imports, utilities) become modulepreload hints only,
|
|
309
|
+
* reducing network/CPU contention.
|
|
310
|
+
*
|
|
311
|
+
* - `'after-lcp'`: Scripts download immediately via modulepreload but execution is deferred
|
|
312
|
+
* until after first paint using double requestAnimationFrame. This allows the browser to
|
|
313
|
+
* paint the SSR content before executing JavaScript. Only applies to SSG pages.
|
|
314
|
+
*
|
|
315
|
+
* - `'after-lcp-aggressive'`: Only modulepreloads critical scripts (entry, layouts).
|
|
316
|
+
* Non-critical scripts have no modulepreload hints, reducing network saturation.
|
|
317
|
+
* Best for pages with many chunks or slow networks.
|
|
318
|
+
*
|
|
319
|
+
* @default undefined (all scripts load with async)
|
|
320
|
+
*/
|
|
321
|
+
experimental_scriptLoading?: 'defer-non-critical' | 'after-lcp' | 'after-lcp-aggressive';
|
|
303
322
|
/**
|
|
304
323
|
* Generate a sitemap.xml file during build.
|
|
305
324
|
*
|
|
@@ -390,7 +409,12 @@ export declare namespace One {
|
|
|
390
409
|
serverJsPath: string;
|
|
391
410
|
params: Object;
|
|
392
411
|
loaderData: any;
|
|
412
|
+
/** All preloads (for backwards compatibility) */
|
|
393
413
|
preloads: string[];
|
|
414
|
+
/** Critical preloads that load immediately with async */
|
|
415
|
+
criticalPreloads?: string[];
|
|
416
|
+
/** Non-critical preloads that are modulepreload hints only */
|
|
417
|
+
deferredPreloads?: string[];
|
|
394
418
|
css: string[];
|
|
395
419
|
/** When inlineLayoutCSS is enabled, contains the actual CSS content */
|
|
396
420
|
cssContents?: string[];
|
|
@@ -399,6 +423,8 @@ export declare namespace One {
|
|
|
399
423
|
css?: string[];
|
|
400
424
|
/** When inlineLayoutCSS is enabled, this contains the actual CSS content to inline */
|
|
401
425
|
cssContents?: string[];
|
|
426
|
+
/** Number of inline CSS entries - used for hydration matching when cssContents is stripped */
|
|
427
|
+
cssInlineCount?: number;
|
|
402
428
|
postRenderData?: any;
|
|
403
429
|
loaderData?: any;
|
|
404
430
|
loaderProps?: any;
|