Skip to content
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

Add fetchpriority option for link + Fix prefetch url in dev mode #6824

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 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
5 changes: 5 additions & 0 deletions .changeset/fuzzy-pumas-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@builder.io/qwik': patch
---

Support fetchpriority attribute for linkInsert prefetch strategy
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 @@ -82,7 +82,7 @@
}
],
"kind": "Interface",
"content": "```typescript\nexport interface PrefetchImplementation \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[linkInsert?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'js-append' \\| 'html-append' \\| null\n\n\n</td><td>\n\n_(Optional)_ `js-append`<!-- -->: Use JS runtime to create each `<link>` and append to the body.\n\n`html-append`<!-- -->: Render each `<link>` within html, appended at the end of the body.\n\n\n</td></tr>\n<tr><td>\n\n[linkRel?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'prefetch' \\| 'preload' \\| 'modulepreload' \\| null\n\n\n</td><td>\n\n_(Optional)_ Value of the `<link rel=\"...\">` attribute when link is used. Defaults to `prefetch` if links are inserted.\n\n\n</td></tr>\n<tr><td>\n\n[prefetchEvent?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'always' \\| null\n\n\n</td><td>\n\n_(Optional)_ Dispatch a `qprefetch` event with detail data containing the bundles that should be prefetched. The event dispatch script will be inlined into the document's HTML so any listeners of this event should already be ready to handle the event.\n\nThis implementation will inject a script similar to:\n\n```\n<script type=\"module\">\n document.dispatchEvent(new CustomEvent(\"qprefetch\", { detail:{ \"bundles\": [...] } }))\n</script>\n```\nBy default, the `prefetchEvent` implementation will be set to `always`<!-- -->.\n\n\n</td></tr>\n<tr><td>\n\n[workerFetchInsert?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'always' \\| 'no-link-support' \\| null\n\n\n</td><td>\n\n_(Optional)_ `always`<!-- -->: Always include the worker fetch JS runtime.\n\n`no-link-support`<!-- -->: Only include the worker fetch JS runtime when the browser doesn't support `<link>` prefetch/preload/modulepreload.\n\n\n</td></tr>\n</tbody></table>",
"content": "```typescript\nexport interface PrefetchImplementation \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[linkFetchPriority?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'auto' \\| 'low' \\| 'high' \\| null\n\n\n</td><td>\n\n_(Optional)_ Value of the `<link fetchpriority=\"...\">` attribute when link is used. Defaults to `null` if links are inserted.\n\n\n</td></tr>\n<tr><td>\n\n[linkInsert?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'js-append' \\| 'html-append' \\| null\n\n\n</td><td>\n\n_(Optional)_ `js-append`<!-- -->: Use JS runtime to create each `<link>` and append to the body.\n\n`html-append`<!-- -->: Render each `<link>` within html, appended at the end of the body.\n\n\n</td></tr>\n<tr><td>\n\n[linkRel?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'prefetch' \\| 'preload' \\| 'modulepreload' \\| null\n\n\n</td><td>\n\n_(Optional)_ Value of the `<link rel=\"...\">` attribute when link is used. Defaults to `prefetch` if links are inserted.\n\n\n</td></tr>\n<tr><td>\n\n[prefetchEvent?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'always' \\| null\n\n\n</td><td>\n\n_(Optional)_ Dispatch a `qprefetch` event with detail data containing the bundles that should be prefetched. The event dispatch script will be inlined into the document's HTML so any listeners of this event should already be ready to handle the event.\n\nThis implementation will inject a script similar to:\n\n```\n<script type=\"module\">\n document.dispatchEvent(new CustomEvent(\"qprefetch\", { detail:{ \"bundles\": [...] } }))\n</script>\n```\nBy default, the `prefetchEvent` implementation will be set to `always`<!-- -->.\n\n\n</td></tr>\n<tr><td>\n\n[workerFetchInsert?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n'always' \\| 'no-link-support' \\| null\n\n\n</td><td>\n\n_(Optional)_ `always`<!-- -->: Always include the worker fetch JS runtime.\n\n`no-link-support`<!-- -->: Only include the worker fetch JS runtime when the browser doesn't support `<link>` prefetch/preload/modulepreload.\n\n\n</td></tr>\n</tbody></table>",
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts",
"mdFile": "qwik.prefetchimplementation.md"
},
Expand Down
15 changes: 15 additions & 0 deletions packages/docs/src/routes/api/qwik-server/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,21 @@ Description
</th></tr></thead>
<tbody><tr><td>

[linkFetchPriority?](#)

</td><td>

</td><td>

'auto' \| 'low' \| 'high' \| null

</td><td>

_(Optional)_ Value of the `<link fetchpriority="...">` attribute when link is used. Defaults to `null` if links are inserted.

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

[linkInsert?](#)

</td><td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export default function (opts: RenderToStreamOptions) {
| `prefetchEvent` | Dispatch a `qprefetch` event with `detail` data containing the urls that should be prefetched. The event dispatch script will be inlined into the document's HTML. By default, the `prefetchEvent` implementation will be set to `always`. |
| `linkInsert` | Insert the `<link>` element into the document. When using `html-append`, it will render each `<link>` directly within the html, appended at the end of the body. Using the `js-append` option, it will instead insert some JavaScript, which creates the elements at runtime and appends them at the end of the body. |
| `linkRel` | This option is used to define the [`rel` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types) of the `<link>` element. When the `linkInsert` option is used, the default is `prefetch`. Other options include `preload` and `modulepreload`. |
| `linkFetchPriority` | This option is used to define the [`fetchpriority` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#fetchpriority) of the `<link>` element. When the `linkInsert` option is used, the default is `null`. Other options include `low`, `high` and `auto`. |
| `workerFetchInsert` | Prefetch urls by calling a `fetch()` for each module, with the goal of populating the network cache. |

#### Dispatched Prefetch Event
Expand Down
1 change: 1 addition & 0 deletions packages/qwik/src/server/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export type InOrderStreaming = InOrderAuto | InOrderDisabled | InOrderDirect;

// @public (undocumented)
export interface PrefetchImplementation {
linkFetchPriority?: 'auto' | 'low' | 'high' | null;
linkInsert?: 'js-append' | 'html-append' | null;
linkRel?: 'prefetch' | 'preload' | 'modulepreload' | null;
prefetchEvent?: 'always' | null;
Expand Down
9 changes: 9 additions & 0 deletions packages/qwik/src/server/prefetch-implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,15 @@ function linkHtmlImplementation(
) {
const urls = flattenPrefetchResources(prefetchResources);
const rel = prefetchImpl.linkRel || 'prefetch';
const priority = prefetchImpl.linkFetchPriority;

for (const url of urls) {
const attributes: Record<string, string> = {};
attributes['href'] = url;
attributes['rel'] = rel;
if (priority) {
attributes['fetchpriority'] = priority;
}
if (rel === 'prefetch' || rel === 'preload') {
if (url.endsWith('.js')) {
attributes['as'] = 'script';
Expand All @@ -101,6 +105,7 @@ function linkJsImplementation(
nonce?: string
) {
const rel = prefetchImpl.linkRel || 'prefetch';
const priority = prefetchImpl.linkFetchPriority;
let s = ``;

if (prefetchImpl.workerFetchInsert === 'no-link-support') {
Expand All @@ -113,6 +118,9 @@ function linkJsImplementation(
s += `const l=document.createElement('link');`;
s += `l.setAttribute("href",u);`;
s += `l.setAttribute("rel","${rel}");`;
if (priority) {
s += `l.setAttribute("fetchpriority","${priority}");`;
}

if (prefetchImpl.workerFetchInsert === 'no-link-support') {
s += `if(i===0){`;
Expand Down Expand Up @@ -173,6 +181,7 @@ function normalizePrefetchImplementation(
const PrefetchImplementationDefault: Required<PrefetchImplementation> = {
linkInsert: null,
linkRel: null,
linkFetchPriority: null,
workerFetchInsert: null,
prefetchEvent: 'always',
};
3 changes: 2 additions & 1 deletion packages/qwik/src/server/prefetch-strategy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getBuildBase } from './utils';
import { qDev } from '../core/util/qdev';
import type {
PrefetchResource,
QwikManifest,
Expand Down Expand Up @@ -77,7 +78,7 @@ function addBundle(
buildBase: string,
bundleFileName: string
) {
const url = buildBase + bundleFileName;
const url = qDev ? bundleFileName : buildBase + bundleFileName;
let prefetchResource = urls.get(url);
if (!prefetchResource) {
prefetchResource = {
Expand Down
5 changes: 5 additions & 0 deletions packages/qwik/src/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ export interface PrefetchImplementation {
* are inserted.
*/
linkRel?: 'prefetch' | 'preload' | 'modulepreload' | null;
/**
* Value of the `<link fetchpriority="...">` attribute when link is used. Defaults to `null` if
* links are inserted.
*/
linkFetchPriority?: 'auto' | 'low' | 'high' | null;
/**
* `always`: Always include the worker fetch JS runtime.
*
Expand Down