Skip to content

Commit b055c8f

Browse files
committed
perf(preload): refactor bundlegraph fetch
- use json again because overall it takes less time to parse - don't preload so that the critical bundles have precedence - don't exclude preloader from critical bundles
1 parent e77d8c5 commit b055c8f

File tree

5 files changed

+18
-24
lines changed

5 files changed

+18
-24
lines changed

packages/docs/src/routes/docs/(qwikcity)/advanced/speculative-module-fetching/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ However, Qwik knows the module graph and controls QRL segment loading, we do kno
6262

6363
The Qwik build process generates a `q-manifest.json` file. The `q-manifest.json` includes a detailed module graph of how bundles are associated and which symbols are within each bundle.
6464

65-
This is then further used to generate the `build/q-bundle-graph-xyz.js` file, which is a compact representation of the module graph, including probabilities of which bundlers are more likely to be requested next given a certain bundle has loaded, and is loaded by Qwik to preload QRL segment loading.
65+
This is then further used to generate the `build/q-bundle-graph-xyz.json` file, which is a compact representation of the module graph, including probabilities of which bundlers are more likely to be requested next given a certain bundle has loaded, and is loaded by Qwik to preload QRL segment loading.
6666

6767
Qwik-City also injects all routes with their dependencies into this bundlegraph file.
6868

packages/qwik/src/core/preloader/bundle-graph.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export const getBundle = (name: string) => {
7373
/** Used in browser */
7474
export const loadBundleGraph = (
7575
basePath: string,
76-
manifestHash: string,
76+
serializedResponse?: ReturnType<typeof fetch>,
7777
opts?: {
7878
/** Enable logging */
7979
debug?: boolean;
@@ -99,10 +99,11 @@ export const loadBundleGraph = (
9999
}
100100
base = basePath;
101101

102-
if (manifestHash) {
103-
import(/* @vite-ignore */ `${basePath}q-bundle-graph-${manifestHash}.js`)
104-
.then((m) => {
105-
graph = parseBundleGraph(m.B);
102+
if (serializedResponse) {
103+
serializedResponse
104+
.then((r) => r.text())
105+
.then((text) => {
106+
graph = parseBundleGraph(JSON.parse(text));
106107
const toAdjust: [BundleImport, number][] = [];
107108
for (const [name, deps] of graph.entries()) {
108109
const bundle = getBundle(name)!;

packages/qwik/src/optimizer/src/plugins/bundle-graph.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,6 @@ export function convertManifestToBundleGraph(
6464
}
6565
}
6666

67-
// Remove the preloader, it will already be loaded and has no dependencies
68-
if (manifest.preloader) {
69-
delete graph[manifest.preloader];
70-
}
71-
7267
// Filter out external and non-segment dynamic imports
7368
for (const bundleName of Object.keys(graph)) {
7469
const bundle = graph[bundleName];

packages/qwik/src/optimizer/src/plugins/plugin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -954,9 +954,9 @@ export const manifest = ${JSON.stringify(serverManifest)};\n`;
954954
fileName: optimizer.sys.path.join(
955955
useAssetsDir ? assetsDir : '',
956956
'build',
957-
`q-bundle-graph-${manifest.manifestHash}.js`
957+
`q-bundle-graph-${manifest.manifestHash}.json`
958958
),
959-
source: `export const B=${JSON.stringify(bundleGraph)}`,
959+
source: JSON.stringify(bundleGraph),
960960
});
961961

962962
manifest.bundleGraph = bundleGraph;

packages/qwik/src/server/prefetch-implementation.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,7 @@ export function includePreloader(
4747
return jsx('link', linkProps as any);
4848
};
4949

50-
const preloadChunk = manifest?.manifest.preloader;
5150
const manifestHash = manifest?.manifest.manifestHash;
52-
if (allowed && preloadChunk) {
53-
allowed--;
54-
nodes.push(makeLink(base, preloadChunk!));
55-
if (allowed && manifestHash) {
56-
allowed--;
57-
nodes.push(makeLink(base, `q-bundle-graph-${manifestHash}.js`));
58-
}
59-
}
6051
if (allowed) {
6152
const expandedBundles = expandBundles(referencedBundles, manifest);
6253
// Keep the same as in expandBundles (but *10)
@@ -76,6 +67,8 @@ export function includePreloader(
7667
}
7768
}
7869
}
70+
71+
const preloadChunk = manifestHash && manifest?.manifest.preloader;
7972
if (preloadChunk) {
8073
const opts: string[] = [];
8174
if (debug) {
@@ -88,16 +81,21 @@ export function includePreloader(
8881
opts.push(`Q:${minPreloadProbability}`);
8982
}
9083
const optsStr = opts.length ? `,{${opts.join(',')}}` : '';
84+
const script = `let b=fetch("${base}q-bundle-graph-${manifestHash}.json");import("${base}${preloadChunk}").then(({l,p})=>{l(${JSON.stringify(base)},b${optsStr});p(${JSON.stringify(referencedBundles)});})`;
9185
/**
9286
* Uses the preloader chunk to add the `<link>` elements at runtime. This allows core to simply
9387
* import the preloader as well and have all the state there, plus it makes it easy to write a
9488
* complex implementation.
89+
*
90+
* Note that we don't preload the preloader or bundlegraph, they are requested after the SSR
91+
* preloads because they are not as important. Also the preloader includes the vitePreload
92+
* function and will in fact already be in that list.
9593
*/
9694
nodes.push(
9795
jsx('script', {
9896
type: 'module',
9997
'q:type': 'link-js',
100-
dangerouslySetInnerHTML: `import("${base}${preloadChunk}").then(({l,p})=>{l(${JSON.stringify(base)}${manifestHash ? `,${JSON.stringify(manifestHash)}` : ''}${optsStr});p(${JSON.stringify(referencedBundles)});})`,
98+
dangerouslySetInnerHTML: script,
10199
nonce,
102100
})
103101
);
@@ -117,7 +115,7 @@ function normalizePrefetchImplementation(
117115
}
118116

119117
const PrefetchImplementationDefault: Required<PrefetchImplementation> = {
120-
maxPreloads: import.meta.env.DEV ? 10 : 5,
118+
maxPreloads: import.meta.env.DEV ? 15 : 7,
121119
minProbability: 0.6,
122120
debug: false,
123121
maxSimultaneousPreloads: 5,

0 commit comments

Comments
 (0)