Skip to content

Commit 1bdcf2d

Browse files
committed
Merge branch 'main' of https://github.com/Shane-Donlon/qwik into docs-e2e-page-loads
2 parents 5734cca + 0ab5665 commit 1bdcf2d

File tree

11 files changed

+1502
-19
lines changed

11 files changed

+1502
-19
lines changed

.changeset/sixty-rockets-clean.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@builder.io/qwik-city': patch
3+
---
4+
5+
FEAT: SPA Link navigation now preloads the next route bundles on click with maximum probability, speeding up SPA navigation.

.changeset/wise-worlds-hang.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+
CHORE: use patched domino instead of qwik-dom

packages/qwik-city/src/runtime/src/client-navigate.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ export const newScrollState = (): ScrollState => {
4141
};
4242
};
4343

44-
export const prefetchSymbols = (path: string) => {
44+
export const preloadRouteBundles = (path: string, probability: number = 0.8) => {
4545
if (isBrowser) {
4646
path = path.endsWith('/') ? path : path + '/';
4747
path = path.length > 1 && path.startsWith('/') ? path.slice(1) : path;
48-
preload(path, 0.8);
48+
preload(path, probability);
4949
}
5050
};

packages/qwik-city/src/runtime/src/link-component.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ import {
1313
import { getClientNavPath, shouldPreload } from './utils';
1414
import { loadClientData } from './use-endpoint';
1515
import { useLocation, useNavigate } from './use-functions';
16-
import { prefetchSymbols } from './client-navigate';
16+
import { preloadRouteBundles } from './client-navigate';
1717
import { isDev } from '@builder.io/qwik';
18+
// @ts-expect-error we don't have types for the preloader yet
19+
import { p as preload } from '@builder.io/qwik/preloader';
1820

1921
/** @public */
2022
export const Link = component$<LinkProps>((props) => {
@@ -51,28 +53,30 @@ export const Link = component$<LinkProps>((props) => {
5153

5254
if (elm && elm.href) {
5355
const url = new URL(elm.href);
54-
prefetchSymbols(url.pathname);
56+
preloadRouteBundles(url.pathname);
5557

5658
if (elm.hasAttribute('data-prefetch')) {
5759
loadClientData(url, elm, {
58-
prefetchSymbols: false,
60+
preloadRouteBundles: false,
5961
isPrefetch: true,
6062
});
6163
}
6264
}
6365
})
6466
: undefined;
67+
6568
const preventDefault = clientNavPath
6669
? sync$((event: MouseEvent, target: HTMLAnchorElement) => {
6770
if (!(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {
6871
event.preventDefault();
6972
}
7073
})
7174
: undefined;
72-
const handleClick = clientNavPath
75+
76+
const handleClientSideNavigation = clientNavPath
7377
? $(async (event: Event, elm: HTMLAnchorElement) => {
7478
if (event.defaultPrevented) {
75-
// If default was prevented, than it is up to us to make client side navigation.
79+
// If default was prevented, then it is up to us to make client side navigation.
7680
if (elm.hasAttribute('q:nbs')) {
7781
// Allow bootstrapping into useNavigate.
7882
await nav(location.href, { type: 'popstate' });
@@ -85,6 +89,11 @@ export const Link = component$<LinkProps>((props) => {
8589
})
8690
: undefined;
8791

92+
const handlePreload = $((_: any, elm: HTMLAnchorElement) => {
93+
const url = new URL(elm.href);
94+
preloadRouteBundles(url.pathname, 1);
95+
});
96+
8897
useVisibleTask$(({ track }) => {
8998
track(() => loc.url.pathname);
9099
// We need to trigger the onQVisible$ in the visible task for it to fire on subsequent route navigations
@@ -115,7 +124,12 @@ export const Link = component$<LinkProps>((props) => {
115124
// Attr 'q:link' is used as a selector for bootstrapping into spa after context loss
116125
{...{ 'q:link': !!clientNavPath }}
117126
{...linkProps}
118-
onClick$={[preventDefault, onClick$, handleClick]}
127+
onClick$={[
128+
preventDefault,
129+
handlePreload, // needs to be in between preventDefault and onClick$ to ensure it starts asap.
130+
onClick$,
131+
handleClientSideNavigation,
132+
]}
119133
data-prefetch={prefetchData}
120134
onMouseOver$={[linkProps.onMouseOver$, handlePrefetch]}
121135
onFocus$={[linkProps.onFocus$, handlePrefetch]}

packages/qwik-city/src/runtime/src/use-endpoint.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import { getClientDataPath } from './utils';
22
import { CLIENT_DATA_CACHE } from './constants';
33
import type { ClientPageData, RouteActionValue } from './types';
44
import { _deserializeData } from '@builder.io/qwik';
5-
import { prefetchSymbols } from './client-navigate';
5+
import { preloadRouteBundles } from './client-navigate';
66

77
export const loadClientData = async (
88
url: URL,
99
element: unknown,
1010
opts?: {
1111
action?: RouteActionValue;
1212
clearCache?: boolean;
13-
prefetchSymbols?: boolean;
13+
preloadRouteBundles?: boolean;
1414
isPrefetch?: boolean;
1515
}
1616
) => {
@@ -22,8 +22,8 @@ export const loadClientData = async (
2222
qData = CLIENT_DATA_CACHE.get(clientDataPath);
2323
}
2424

25-
if (opts?.prefetchSymbols !== false) {
26-
prefetchSymbols(pagePathname);
25+
if (opts?.preloadRouteBundles !== false) {
26+
preloadRouteBundles(pagePathname, 0.8);
2727
}
2828
let resolveFn: () => void | undefined;
2929

packages/qwik/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
},
3131
"devDependencies": {
3232
"@builder.io/qwik": "workspace:^",
33-
"@builder.io/qwik-dom": "workspace:^",
33+
"domino": "2.1.6",
3434
"ignore": "5.3.1",
3535
"image-size": "1.1.1",
3636
"kleur": "4.1.5",

packages/qwik/src/testing/document.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { MockDocumentOptions, MockWindow } from './types';
2-
import qwikDom from '@builder.io/qwik-dom';
2+
import domino from 'domino';
33
import { normalizeUrl } from './util';
44

55
/**
@@ -9,7 +9,7 @@ import { normalizeUrl } from './util';
99
* @public
1010
*/
1111
export function createDocument(opts?: MockDocumentOptions) {
12-
const doc = qwikDom.createDocument(opts?.html);
12+
const doc = domino.createDocument(opts?.html);
1313
ensureGlobals(doc, opts);
1414
return doc;
1515
}

0 commit comments

Comments
 (0)