Skip to content

Commit 23ed7db

Browse files
authored
Merge pull request #7506 from QwikDev/fix-preload-ssr
fix(ssr): preloading fixes and tweaks
2 parents 7885598 + d9446cf commit 23ed7db

File tree

10 files changed

+174
-159
lines changed

10 files changed

+174
-159
lines changed

.changeset/slick-candies-rhyme.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@builder.io/qwik': patch
3+
---
4+
5+
FIX: now qwikloader is loaded only once in all cases

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: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
maxSignificantInverseProbabilityStr,
66
maxSimultaneousPreloadsStr,
77
} from './constants';
8-
import { adjustProbabilities, bundles, log, trigger } from './queue';
8+
import { adjustProbabilities, bundles, log, shouldResetFactor, trigger } from './queue';
99
import type { BundleGraph, BundleImport, ImportProbability } from './types';
1010
import { BundleImportState_None, BundleImportState_Alias } from './types';
1111

@@ -22,7 +22,7 @@ const makeBundle = (name: string, deps?: ImportProbability[]) => {
2222
$name$: name,
2323
$url$: url,
2424
$state$: url ? BundleImportState_None : BundleImportState_Alias,
25-
$deps$: deps,
25+
$deps$: shouldResetFactor ? deps?.map((d) => ({ ...d, $factor$: 1 })) : deps,
2626
$inverseProbability$: 1,
2727
$createdTs$: Date.now(),
2828
$waitedMs$: 0,
@@ -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/core/preloader/queue.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
} from './types';
1818

1919
export const bundles: BundleImports = new Map();
20+
export let shouldResetFactor: boolean;
2021
let queueDirty: boolean;
2122
let preloadCount = 0;
2223
const queue: BundleImport[] = [];
@@ -32,6 +33,7 @@ export const log = (...args: any[]) => {
3233
export const resetQueue = () => {
3334
bundles.clear();
3435
queueDirty = false;
36+
shouldResetFactor = true;
3537
preloadCount = 0;
3638
queue.length = 0;
3739
};
@@ -178,6 +180,7 @@ export const adjustProbabilities = (
178180
if (bundle.$deps$) {
179181
seen ||= new Set();
180182
seen.add(bundle);
183+
const probability = 1 - bundle.$inverseProbability$;
181184
for (const dep of bundle.$deps$) {
182185
const depBundle = getBundle(dep.$name$)!;
183186
const prevAdjust = dep.$factor$;
@@ -188,7 +191,7 @@ export const adjustProbabilities = (
188191
* We can multiply this chance together with all other bundle adjustments to get the chance
189192
* that a dep will be loaded given all the chances of the other bundles
190193
*/
191-
const newInverseProbability = 1 - dep.$probability$ * (1 - bundle.$inverseProbability$);
194+
const newInverseProbability = 1 - dep.$probability$ * probability;
192195

193196
/** We need to undo the previous adjustment */
194197
const factor = newInverseProbability / prevAdjust;

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

Lines changed: 7 additions & 8 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];
@@ -143,8 +138,8 @@ export function convertManifestToBundleGraph(
143138
// Calculate the probability of the dependency
144139
// Start with a 50% chance
145140
let probability = 0.5;
146-
// Add a 4% chance for each interactivity point (max 20%)
147-
probability += (dep.interactivity || 0) * 0.04;
141+
// Add a 8% chance for each interactivity point (max 40%)
142+
probability += (dep.interactivity || 0) * 0.08;
148143

149144
// If the dependency has a segment from the same parent, it's more likely to be loaded
150145
if (bundle.origins && dep.origins) {
@@ -161,8 +156,12 @@ export function convertManifestToBundleGraph(
161156
if (dep.total > slowSize) {
162157
probability += probability > 0.5 ? 0.02 : -0.02;
163158
}
159+
// OTOH, if the dependency is small, load it sooner since it won't block much
160+
if (dep.total < 1000) {
161+
probability += 0.15;
162+
}
164163

165-
depProbability.set(depName, probability);
164+
depProbability.set(depName, Math.min(probability, 0.99));
166165
}
167166

168167
if (dynDeps.size > 0) {

0 commit comments

Comments
 (0)