Skip to content

Commit 9f29490

Browse files
hadyanXhmikosR
andauthored
Update Prerender Support (#352)
* remove 1 prerender limit, same origin checking, and pre-existing spec rules checking * minor convention fixes * Update the related prerendering docs on the API docs site * Adapt .size-limit.json * minor documentation reference link update to use shortener --------- Co-authored-by: XhmikosR <[email protected]>
1 parent cd509b9 commit 9f29490

File tree

5 files changed

+26
-40
lines changed

5 files changed

+26
-40
lines changed

.size-limit.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
[
22
{
33
"path": "dist/quicklink.js",
4-
"limit": "2.05 kB"
4+
"limit": "2 kB"
55
},
66
{
77
"path": "dist/quicklink.mjs",
8-
"limit": "2.05 kB"
8+
"limit": "2 kB"
99
},
1010
{
1111
"path": "dist/quicklink.modern.mjs",
12-
"limit": "1.75 kB"
12+
"limit": "1.6 kB"
1313
},
1414
{
1515
"path": "dist/quicklink.umd.js",
16-
"limit": "2.1 kB"
16+
"limit": "2 kB"
1717
}
1818
]

README.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ Whether to switch from the default prefetching mode to the prerendering mode for
127127

128128
> **Note:** The prerendering mode (when this option is set to true) will fallback to the prefetching mode if the browser does not support prerender.
129129
130+
#### options.prerenderAndPrefetch
131+
132+
* Type: `Boolean`
133+
* Default: `false`
134+
135+
Whether to activate both the prefetching and prerendering mode at the same time.
136+
130137
#### options.delay
131138

132139
- Type: `Number`
@@ -146,7 +153,7 @@ The DOM element to observe for in-viewport links to prefetch or the NodeList of
146153
- Type: `Number`
147154
- Default: `Infinity`
148155

149-
The _total_ requests that can be prefetched while observing the `options.el` container.
156+
The _total_ requests that can be prefetched or prerendered while observing the `options.el` container.
150157

151158
#### options.threshold
152159

@@ -272,7 +279,7 @@ Returns: `Promise`
272279

273280
One or many URLs to be prerendered.
274281

275-
> **Note:** As prerendering using Speculative Rules API only supports same-origin at this point, only same-origin urls are accepted. Any non same-origin urls will return a rejected Promise.
282+
> **Note:** Speculative Rules API supports same-site cross origin Prerendering with [opt-in header](https://bit.ly/ss-cross-origin-pre).
276283
277284
## Polyfills
278285

site/src/api.njk

+9-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ Whether to switch from the default prefetching mode to the prerendering mode for
3131

3232
> **Note:** The prerendering mode (when this option is set to true) will fallback to the prefetching mode if the browser does not support prerender.
3333

34+
#### options.prerenderAndPrefetch
35+
36+
* Type: `Boolean`
37+
* Default: `false`
38+
39+
Whether to activate both the prefetching and prerendering mode at the same time.
40+
3441
#### options.delay
3542

3643
- Type: `Number`
@@ -50,7 +57,7 @@ The DOM element to observe for in-viewport links to prefetch or the NodeList of
5057
- Type: `Number`
5158
- Default: `Infinity`
5259

53-
The _total_ requests that can be prefetched while observing the `options.el` container.
60+
The _total_ requests that can be prefetched or prerendered while observing the `options.el` container.
5461

5562
#### options.threshold
5663

@@ -176,7 +183,7 @@ Returns: `Promise`
176183

177184
One or many URLs to be prerendered.
178185

179-
> **Note:** As prerendering using Speculative Rules API only supports same-origin at this point, only same-origin urls are accepted. Any non same-origin urls will return a rejected Promise.
186+
> **Note:** Speculative Rules API supports same-site cross origin Prerendering with [opt-in header](https://bit.ly/ss-cross-origin-pre).
180187

181188
## Polyfills
182189

src/index.mjs

+4-15
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import throttle from 'throttles';
1818
import {priority, supported} from './prefetch.mjs';
1919
import requestIdleCallback from './request-idle-callback.mjs';
20-
import {isSameOrigin, addSpeculationRules, hasSpecRulesSupport, isSpecRulesExists} from './prerender.mjs';
20+
import {addSpeculationRules, hasSpecRulesSupport} from './prerender.mjs';
2121

2222
// Cache of URLs we've prefetched
2323
// Its `size` is compared against `opts.limit` value.
@@ -105,8 +105,6 @@ export function listen(options = {}) {
105105
const shouldOnlyPrerender = options.prerender || false;
106106
shouldPrerenderAndPrefetch = options.prerenderAndPrefetch || false;
107107

108-
const prerenderLimit = 1;
109-
110108
const setTimeoutIfDelay = (callback, delay) => {
111109
if (!delay) {
112110
callback();
@@ -133,8 +131,8 @@ export function listen(options = {}) {
133131

134132
// prerender, if..
135133
// either it's the prerender + prefetch mode or it's prerender *only* mode
136-
// && no link has been prerendered before (no spec rules defined)
137-
if ((shouldPrerenderAndPrefetch || shouldOnlyPrerender) && toPrerender.size < prerenderLimit) {
134+
// Prerendering limit is following options.limit. UA may impose arbitraty numeric limit
135+
if ((shouldPrerenderAndPrefetch || shouldOnlyPrerender) && toPrerender.size < limit) {
138136
prerender(hrefFn ? hrefFn(entry) : entry.href).catch(error => {
139137
if (options.onError) {
140138
options.onError(error);
@@ -245,22 +243,13 @@ export function prerender(urls) {
245243

246244
// prerendering preconditions:
247245
// 1) whether UA supports spec rules.. If not, fallback to prefetch
246+
// Note: Prerendering supports same-site cross origin with opt-in header
248247
if (!hasSpecRulesSupport()) {
249248
prefetch(urls);
250249
return Promise.reject(new Error('This browser does not support the speculation rules API. Falling back to prefetch.'));
251250
}
252251

253-
// 2) whether spec rules is already defined (and with this we also covered when we have created spec rules before)
254-
if (isSpecRulesExists()) {
255-
return Promise.reject(new Error('Speculation Rules is already defined and cannot be altered.'));
256-
}
257-
258-
// 3) whether it's a same origin url,
259252
for (const url of [].concat(urls)) {
260-
if (!isSameOrigin(url)) {
261-
return Promise.reject(new Error(`Only same origin URLs are allowed: ${url}`));
262-
}
263-
264253
toPrerender.add(url);
265254
}
266255

src/prerender.mjs

-17
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,6 @@
1717
* limitations under the License.
1818
**/
1919

20-
/**
21-
* Checks if the given string is a same origin url
22-
* @param {string} str - the URL to check
23-
* @return {Boolean} true for same origin url
24-
*/
25-
export function isSameOrigin(str) {
26-
return window.location.origin === (new URL(str, window.location.href)).origin;
27-
}
28-
2920
/**
3021
* Add a given set of urls to the speculation rules
3122
* @param {Set} urlsToPrerender - the URLs to add to speculation rules
@@ -51,11 +42,3 @@ export function addSpeculationRules(urlsToPrerender) {
5142
export function hasSpecRulesSupport() {
5243
return HTMLScriptElement.supports('speculationrules');
5344
}
54-
55-
/**
56-
* Check whether Spec Rules is already defined in the document
57-
* @return {Boolean} whether Spec Rules exists/already defined
58-
*/
59-
export function isSpecRulesExists() {
60-
return document.querySelector('script[type="speculationrules"]');
61-
}

0 commit comments

Comments
 (0)