Skip to content

Commit 3676bb4

Browse files
committed
chore: perf improvement for web gen
1 parent bdedcb2 commit 3676bb4

File tree

1 file changed

+46
-25
lines changed

1 file changed

+46
-25
lines changed

src/generators/web/utils/processing.mjs

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,38 @@ import { SPECULATION_RULES } from '../constants.mjs';
77
import bundleCode from './bundle.mjs';
88
import { createChunkedRequire } from './chunks.mjs';
99

10+
/**
11+
* Converts JSX AST entries to server and client JavaScript code.
12+
* This is the CPU-intensive step that can be parallelized.
13+
*
14+
* @param {Array<import('../../jsx-ast/utils/buildContent.mjs').JSXContent>} entries - JSX AST entries
15+
* @param {function} buildServerProgram - Wraps code for server execution
16+
* @param {function} buildClientProgram - Wraps code for client hydration
17+
* @returns {{serverCodeMap: Map<string, string>, clientCodeMap: Map<string, string>}}
18+
*/
19+
export function convertJSXToCode(
20+
entries,
21+
{ buildServerProgram, buildClientProgram }
22+
) {
23+
const serverCodeMap = new Map();
24+
const clientCodeMap = new Map();
25+
26+
for (const entry of entries) {
27+
const fileName = `${entry.data.api}.jsx`;
28+
29+
// Convert AST to JavaScript string with JSX syntax
30+
const { value: code } = toJs(entry, { handlers: jsx });
31+
32+
// Prepare code for server-side execution (wrapped for SSR)
33+
serverCodeMap.set(fileName, buildServerProgram(code));
34+
35+
// Prepare code for client-side execution (wrapped for hydration)
36+
clientCodeMap.set(fileName, buildClientProgram(code));
37+
}
38+
39+
return { serverCodeMap, clientCodeMap };
40+
}
41+
1042
/**
1143
* Executes server-side JavaScript code in an isolated context with virtual module support.
1244
*
@@ -56,38 +88,27 @@ export async function executeServerCode(serverCodeMap, requireFn) {
5688
export async function processJSXEntries(
5789
entries,
5890
template,
59-
{ buildServerProgram, buildClientProgram },
91+
astBuilders,
6092
requireFn,
6193
{ version }
6294
) {
63-
const serverCodeMap = new Map();
64-
const clientCodeMap = new Map();
65-
66-
// Convert JSX AST to JavaScript for both server and client
67-
for (const entry of entries) {
68-
const fileName = `${entry.data.api}.jsx`;
69-
70-
// Convert AST to JavaScript string with JSX syntax
71-
const { value: code } = toJs(entry, { handlers: jsx });
72-
73-
// Prepare code for server-side execution (wrapped for SSR)
74-
serverCodeMap.set(fileName, buildServerProgram(code));
75-
76-
// Prepare code for client-side execution (wrapped for hydration)
77-
clientCodeMap.set(fileName, buildClientProgram(code));
78-
}
79-
80-
// Execute all server code at once to get dehydrated HTML
81-
const serverBundle = await executeServerCode(serverCodeMap, requireFn);
82-
83-
// Bundle all client code at once (with code splitting for shared chunks)
84-
const clientBundle = await bundleCode(clientCodeMap);
95+
// Step 1: Convert JSX AST to JavaScript (CPU-intensive, could be parallelized)
96+
const { serverCodeMap, clientCodeMap } = convertJSXToCode(
97+
entries,
98+
astBuilders
99+
);
100+
101+
// Step 2: Bundle server and client code IN PARALLEL
102+
// Both need all entries for code-splitting, but are independent of each other
103+
const [serverBundle, clientBundle] = await Promise.all([
104+
executeServerCode(serverCodeMap, requireFn),
105+
bundleCode(clientCodeMap),
106+
]);
85107

86108
const titleSuffix = `Node.js v${version.version} Documentation`;
87-
88109
const speculationRulesString = JSON.stringify(SPECULATION_RULES, null, 2);
89110

90-
// Process each entry to create final HTML
111+
// Step 3: Create final HTML (could be parallelized in workers)
91112
const results = entries.map(({ data: { api, heading } }) => {
92113
const fileName = `${api}.js`;
93114

0 commit comments

Comments
 (0)