Skip to content

perf(qwikloader): put qwikloader in a separate bundle #7613

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions packages/docs/src/entry.ssr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ export default function (opts: RenderToStreamOptions) {
}
}
return renderToStream(<Root />, {
qwikLoader: {
// The docs can be long so make sure to intercept events before the end of the document.
position: 'top',
},
...opts,
containerAttributes: {
lang: 'en',
Expand Down
3 changes: 3 additions & 0 deletions packages/docs/src/repl/bundled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import qCoreMinMjs from '../../node_modules/@builder.io/qwik/dist/core.min.mjs?r
import qCoreMjs from '../../node_modules/@builder.io/qwik/dist/core.mjs?raw-source';
import qOptimizerCjs from '../../node_modules/@builder.io/qwik/dist/optimizer.cjs?raw-source';
import qPreloaderMjs from '../../node_modules/@builder.io/qwik/dist/preloader.mjs?raw-source';
// we use the debug version for the repl so it's understandable
import qQwikLoaderJs from '../../node_modules/@builder.io/qwik/dist/qwikloader.debug.js?raw-source';
import qServerCjs from '../../node_modules/@builder.io/qwik/dist/server.cjs?raw-source';
import qServerDts from '../../node_modules/@builder.io/qwik/dist/server.d.ts?raw-source';
import qWasmCjs from '../../node_modules/@builder.io/qwik/bindings/qwik.wasm.cjs?raw-source';
Expand Down Expand Up @@ -57,6 +59,7 @@ export const bundled: PkgUrls = {
'/dist/server.cjs': qServerCjs,
'/dist/server.d.ts': qServerDts,
'/dist/preloader.mjs': qPreloaderMjs,
'/dist/qwikloader.js': qQwikLoaderJs,
'/bindings/qwik.wasm.cjs': qWasmCjs,
'/bindings/qwik_wasm_bg.wasm': qWasmBinUrl,
},
Expand Down
8 changes: 7 additions & 1 deletion packages/docs/src/repl/worker/repl-plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,13 @@ export const replResolver = (options: ReplInputOptions, buildMode: 'client' | 's
return rsp.text();
}
}

// this id is unchanged because it's an entry point
if (id === '@builder.io/qwik/qwikloader.js') {
const rsp = await depResponse('@builder.io/qwik', '/qwikloader.js');
if (rsp) {
return rsp.text();
}
}
// We're the fallback, we know all the files
if (/\.[jt]sx?$/.test(id)) {
throw new Error(`load: unknown module ${id}`);
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/src/routes/api/qwik-optimizer/api.json
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@
}
],
"kind": "Interface",
"content": "The metadata of the build. One of its uses is storing where QRL symbols are located.\n\n\n```typescript\nexport interface QwikManifest \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[bundleGraph?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[QwikBundleGraph](#qwikbundlegraph)\n\n\n</td><td>\n\n_(Optional)_ All bundles in a compact graph format with probabilities\n\n\n</td></tr>\n<tr><td>\n\n[bundles](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[fileName: string\\]: [QwikBundle](#qwikbundle)<!-- -->; }\n\n\n</td><td>\n\nAll code bundles, used to know the import graph\n\n\n</td></tr>\n<tr><td>\n\n[core?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n_(Optional)_ The Qwik core bundle fileName\n\n\n</td></tr>\n<tr><td>\n\n[injections?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[GlobalInjections](#globalinjections)<!-- -->\\[\\]\n\n\n</td><td>\n\n_(Optional)_ CSS etc to inject in the document head\n\n\n</td></tr>\n<tr><td>\n\n[manifestHash](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\nContent hash of the manifest, if this changes, the code changed\n\n\n</td></tr>\n<tr><td>\n\n[mapping](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[symbolName: string\\]: string; }\n\n\n</td><td>\n\nWhere QRLs are located\n\n\n</td></tr>\n<tr><td>\n\n[options?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ target?: string; buildMode?: string; entryStrategy?: { type: [EntryStrategy](#entrystrategy)<!-- -->\\['type'\\]; }; }\n\n\n</td><td>\n\n_(Optional)_ The options used to build the manifest\n\n\n</td></tr>\n<tr><td>\n\n[platform?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[name: string\\]: string; }\n\n\n</td><td>\n\n_(Optional)_ The platform used to build the manifest\n\n\n</td></tr>\n<tr><td>\n\n[preloader?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n_(Optional)_ The preloader bundle fileName\n\n\n</td></tr>\n<tr><td>\n\n[symbols](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[symbolName: string\\]: [QwikSymbol](#qwiksymbol)<!-- -->; }\n\n\n</td><td>\n\nQRL symbols\n\n\n</td></tr>\n<tr><td>\n\n[version](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\nThe version of the manifest\n\n\n</td></tr>\n</tbody></table>",
"content": "The metadata of the build. One of its uses is storing where QRL symbols are located.\n\n\n```typescript\nexport interface QwikManifest \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[bundleGraph?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[QwikBundleGraph](#qwikbundlegraph)\n\n\n</td><td>\n\n_(Optional)_ All bundles in a compact graph format with probabilities\n\n\n</td></tr>\n<tr><td>\n\n[bundles](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[fileName: string\\]: [QwikBundle](#qwikbundle)<!-- -->; }\n\n\n</td><td>\n\nAll code bundles, used to know the import graph\n\n\n</td></tr>\n<tr><td>\n\n[core?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n_(Optional)_ The Qwik core bundle fileName\n\n\n</td></tr>\n<tr><td>\n\n[injections?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[GlobalInjections](#globalinjections)<!-- -->\\[\\]\n\n\n</td><td>\n\n_(Optional)_ CSS etc to inject in the document head\n\n\n</td></tr>\n<tr><td>\n\n[manifestHash](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\nContent hash of the manifest, if this changes, the code changed\n\n\n</td></tr>\n<tr><td>\n\n[mapping](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[symbolName: string\\]: string; }\n\n\n</td><td>\n\nWhere QRLs are located\n\n\n</td></tr>\n<tr><td>\n\n[options?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ target?: string; buildMode?: string; entryStrategy?: { type: [EntryStrategy](#entrystrategy)<!-- -->\\['type'\\]; }; }\n\n\n</td><td>\n\n_(Optional)_ The options used to build the manifest\n\n\n</td></tr>\n<tr><td>\n\n[platform?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[name: string\\]: string; }\n\n\n</td><td>\n\n_(Optional)_ The platform used to build the manifest\n\n\n</td></tr>\n<tr><td>\n\n[preloader?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n_(Optional)_ The preloader bundle fileName\n\n\n</td></tr>\n<tr><td>\n\n[qwikLoader?](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\n_(Optional)_ The Qwik loader bundle fileName\n\n\n</td></tr>\n<tr><td>\n\n[symbols](#)\n\n\n</td><td>\n\n\n</td><td>\n\n{ \\[symbolName: string\\]: [QwikSymbol](#qwiksymbol)<!-- -->; }\n\n\n</td><td>\n\nQRL symbols\n\n\n</td></tr>\n<tr><td>\n\n[version](#)\n\n\n</td><td>\n\n\n</td><td>\n\nstring\n\n\n</td><td>\n\nThe version of the manifest\n\n\n</td></tr>\n</tbody></table>",
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/types.ts",
"mdFile": "qwik.qwikmanifest.md"
},
Expand Down
15 changes: 15 additions & 0 deletions packages/docs/src/routes/api/qwik-optimizer/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1538,6 +1538,21 @@ _(Optional)_ The preloader bundle fileName
</td></tr>
<tr><td>

[qwikLoader?](#)

</td><td>

</td><td>

string

</td><td>

_(Optional)_ The Qwik loader bundle fileName

</td></tr>
<tr><td>

[symbols](#)

</td><td>
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/src/routes/api/qwik-server/api.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
}
],
"kind": "Interface",
"content": "```typescript\nexport interface QwikLoaderOptions \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[include?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'always' \\| 'never' \\| 'auto'\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n<tr><td>\n\n[position?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'top' \\| 'bottom'\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n</tbody></table>",
"content": "```typescript\nexport interface QwikLoaderOptions \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[include?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'always' \\| 'never' \\| 'auto'\n\n\n</td><td>\n\n_(Optional)_ Whether to include the qwikloader script in the document. Normally you don't need to worry about this, but in case of multi-container apps using different Qwik versions, you might want to only enable it on one of the containers.\n\nDefaults to `'auto'`<!-- -->.\n\n\n</td></tr>\n<tr><td>\n\n[position?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'top' \\| 'bottom'\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n</tbody></table>",
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts",
"mdFile": "qwik.qwikloaderoptions.md"
},
Expand Down
4 changes: 3 additions & 1 deletion packages/docs/src/routes/api/qwik-server/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,9 @@ Description

</td><td>

_(Optional)_
_(Optional)_ Whether to include the qwikloader script in the document. Normally you don't need to worry about this, but in case of multi-container apps using different Qwik versions, you might want to only enable it on one of the containers.

Defaults to `'auto'`.

</td></tr>
<tr><td>
Expand Down
4 changes: 4 additions & 0 deletions packages/qwik/src/optimizer/src/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,10 @@ export function generateManifestFromBundles(
manifest.preloader = bundleFileName;
} else if (modulePaths.some((m) => /[/\\]qwik[/\\]dist[/\\]core\.[^/]*js$/.test(m))) {
manifest.core = bundleFileName;
} else if (
modulePaths.some((m) => /[/\\]qwik[/\\]dist[/\\]qwikloader(\.debug)?\.[^/]*js$/.test(m))
) {
manifest.qwikLoader = bundleFileName;
}
}

Expand Down
25 changes: 20 additions & 5 deletions packages/qwik/src/optimizer/src/plugins/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,19 @@ export function createQwikPlugin(optimizerOptions: OptimizerOptions = {}) {
debug(`transformedOutputs.clear()`);
clientTransformedOutputs.clear();
serverTransformedOutputs.clear();

if (opts.target === 'client') {
const ql = await _ctx.resolve('@builder.io/qwik/qwikloader.js', undefined, {
skipSelf: true,
});
if (ql) {
_ctx.emitFile({
id: ql.id,
type: 'chunk',
preserveSignature: 'allow-extension',
});
}
}
};

const getIsServer = (viteOpts?: { ssr?: boolean }) => {
Expand Down Expand Up @@ -869,6 +882,7 @@ export const isDev = ${JSON.stringify(isDev)};
mapping: manifest.mapping,
preloader: manifest.preloader,
core: manifest.core,
qwikLoader: manifest.qwikLoader,
};
}
return `// @qwik-client-manifest
Expand Down Expand Up @@ -907,11 +921,12 @@ export const manifest = ${JSON.stringify(serverManifest)};\n`;
function manualChunks(id: string, { getModuleInfo }: Rollup.ManualChunkMeta) {
// The preloader has to stay in a separate chunk if it's a client build
// the vite preload helper must be included or to prevent breaking circular dependencies
if (
opts.target === 'client' &&
(id.endsWith(QWIK_PRELOADER_REAL_ID) || id === '\0vite/preload-helper.js')
) {
return 'qwik-preloader';
if (opts.target === 'client') {
if (id.endsWith(QWIK_PRELOADER_REAL_ID) || id === '\0vite/preload-helper.js') {
return 'qwik-preloader';
} else if (/qwik[\\/]dist[\\/]qwikloader\.js$/.test(id)) {
return 'qwik-loader';
}
}

const module = getModuleInfo(id)!;
Expand Down
1 change: 1 addition & 0 deletions packages/qwik/src/optimizer/src/qwik.optimizer.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ export interface QwikManifest {
[name: string]: string;
};
preloader?: string;
qwikLoader?: string;
symbols: {
[symbolName: string]: QwikSymbol;
};
Expand Down
4 changes: 3 additions & 1 deletion packages/qwik/src/optimizer/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ export interface QwikManifest {
preloader?: string;
/** The Qwik core bundle fileName */
core?: string;
/** The Qwik loader bundle fileName */
qwikLoader?: string;
/** CSS etc to inject in the document head */
injections?: GlobalInjections[];
/** The version of the manifest */
Expand All @@ -249,7 +251,7 @@ export interface QwikManifest {
*/
export type ServerQwikManifest = Pick<
QwikManifest,
'manifestHash' | 'injections' | 'bundleGraph' | 'mapping' | 'preloader' | 'core'
'manifestHash' | 'injections' | 'bundleGraph' | 'mapping' | 'preloader' | 'core' | 'qwikLoader'
>;

/**
Expand Down
Loading