Skip to content

Commit a6945e2

Browse files
Add module preloading at idle time (#1011)
* module preload * low fetch priority * remove font preload * remove sw and prefetch sw * no log * remove inter from component tests * remove sw from component tests
1 parent e92aee4 commit a6945e2

File tree

5 files changed

+87
-36
lines changed

5 files changed

+87
-36
lines changed

apps/component-tests/src/root.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
1-
import {
2-
component$, useStyles$,
3-
PrefetchGraph,
4-
PrefetchServiceWorker
5-
} from '@builder.io/qwik';
1+
import { component$, useStyles$ } from '@builder.io/qwik';
62
import { QwikCityProvider, RouterOutlet } from '@builder.io/qwik-city';
73

84
import { RouterHead } from './components/router-head/router-head';
95
import globalStyles from './global.css?inline';
106

117
import { ThemeProvider } from '@qwik-ui/themes';
128

13-
import '@fontsource-variable/inter';
149
import {
1510
ThemeBaseColors,
1611
ThemeBorderRadiuses,
@@ -29,7 +24,6 @@ export default component$(() => {
2924
*/
3025
useStyles$(globalStyles);
3126

32-
3327
return (
3428
<QwikCityProvider>
3529
<head>
@@ -38,8 +32,6 @@ export default component$(() => {
3832
<RouterHead />
3933
</head>
4034
<body lang="en">
41-
<PrefetchGraph />
42-
<PrefetchServiceWorker />
4335
<ThemeProvider
4436
attribute="class"
4537
enableSystem={false}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { component$, sync$, useOnWindow } from '@builder.io/qwik';
2+
3+
export const ModulePreload = component$(() => {
4+
useOnWindow(
5+
'load',
6+
sync$(async () => {
7+
// for safari support
8+
if (!window.requestIdleCallback) {
9+
window.requestIdleCallback = function (
10+
callback: IdleRequestCallback,
11+
options?: IdleRequestOptions,
12+
): number {
13+
const opts = options || {};
14+
const relaxation = 1;
15+
const timeout = opts.timeout || relaxation;
16+
const start = performance.now();
17+
return setTimeout(function () {
18+
callback({
19+
get didTimeout() {
20+
return opts.timeout
21+
? false
22+
: performance.now() - start - relaxation > timeout;
23+
},
24+
timeRemaining: function () {
25+
return Math.max(0, relaxation + (performance.now() - start));
26+
},
27+
});
28+
}, relaxation) as unknown as number;
29+
};
30+
}
31+
32+
const startPreloading = async () => {
33+
const prefetchScript = document.querySelector(
34+
'script[q\\:type="prefetch-bundles"]',
35+
);
36+
if (!prefetchScript?.textContent) return;
37+
38+
const qChunks = new Set<string>();
39+
40+
// Check prefetch bundles
41+
const content = prefetchScript.textContent;
42+
const match = content.match(/\["prefetch","\/build\/","(.*?)"\]/);
43+
if (match && match[1]) {
44+
match[1].split('","').forEach((chunk) => {
45+
if (chunk.startsWith('q-')) {
46+
qChunks.add(chunk);
47+
}
48+
});
49+
}
50+
51+
qChunks.forEach((chunk) => {
52+
const link = document.createElement('link');
53+
link.rel = 'modulepreload';
54+
link.as = 'script';
55+
link.href = '/' + 'build/' + chunk;
56+
link.fetchPriority = 'low';
57+
document.head.appendChild(link);
58+
});
59+
};
60+
61+
await requestIdleCallback(await startPreloading);
62+
}),
63+
);
64+
65+
return <></>;
66+
});

apps/website/src/root.tsx

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
import {
2-
component$,
3-
useContextProvider,
4-
useStore,
5-
useStyles$,
6-
PrefetchGraph,
7-
PrefetchServiceWorker,
8-
} from '@builder.io/qwik';
1+
import { component$, useContextProvider, useStore, useStyles$ } from '@builder.io/qwik';
92
import { QwikCityProvider, RouterOutlet } from '@builder.io/qwik-city';
103

114
import { APP_STATE_CONTEXT_ID } from './_state/app-state-context-id';
@@ -15,7 +8,6 @@ import globalStyles from './global.css?inline';
158

169
import { ThemeProvider } from '@qwik-ui/themes';
1710

18-
import '@fontsource-variable/inter';
1911
import {
2012
ThemeBaseColors,
2113
ThemeBorderRadiuses,
@@ -24,6 +16,7 @@ import {
2416
ThemePrimaryColors,
2517
ThemeStyles,
2618
} from '@qwik-ui/utils';
19+
import { ModulePreload } from './components/module-preload/module-preload';
2720

2821
export default component$(() => {
2922
/**
@@ -43,6 +36,21 @@ export default component$(() => {
4336

4437
useContextProvider(APP_STATE_CONTEXT_ID, appState);
4538

39+
const unregisterPrefetchServiceWorkers = `
40+
;(function () {
41+
navigator.serviceWorker?.getRegistrations().then((regs) => {
42+
for (const reg of regs) {
43+
if (
44+
reg.active?.scriptURL.includes('service-worker.js') ||
45+
reg.active?.scriptURL.includes('qwik-prefetch-service-worker.js')
46+
) {
47+
reg.unregister();
48+
}
49+
}
50+
});
51+
})();
52+
`;
53+
4654
return (
4755
<QwikCityProvider>
4856
<head>
@@ -51,8 +59,8 @@ export default component$(() => {
5159
<RouterHead />
5260
</head>
5361
<body lang="en">
54-
<PrefetchGraph />
55-
<PrefetchServiceWorker />
62+
<script dangerouslySetInnerHTML={unregisterPrefetchServiceWorkers} />
63+
<ModulePreload />
5664
<ThemeProvider
5765
attribute="class"
5866
enableSystem={false}

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
"@clack/prompts": "^0.7.0",
5555
"@floating-ui/core": "^1.6.2",
5656
"@floating-ui/dom": "^1.6.5",
57-
"@fontsource-variable/inter": "^5.0.18",
5857
"@img/sharp-linux-x64": "^0.33.4",
5958
"@k11r/nx-cloudflare-wrangler": "3.0.0-feat-sst-upgrade.1",
6059
"@modular-forms/qwik": "^0.24.0",

pnpm-lock.yaml

Lines changed: 1 addition & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)