Improve prefetch conditions (#5244)

* Improve prefetch

* Add changeset
This commit is contained in:
Robin Lindner 2022-11-01 13:42:30 +01:00 committed by GitHub
parent 2f8c9a98cc
commit 6ad91bd80d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 17 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/prefetch': patch
---
Do not prefetch if browser is offline or uses 3G

View file

@ -15,7 +15,7 @@ function shouldPreload({ href }: { href: string }) {
window.location.pathname !== url.pathname &&
!preloaded.has(href)
);
} catch {}
} catch { }
return false;
}
@ -44,12 +44,11 @@ function onLinkEvent({ target }: Event) {
async function preloadHref(link: HTMLAnchorElement) {
unobserve(link);
const { href } = link;
try {
const contents = await fetch(href).then((res) => res.text());
parser = parser || new DOMParser();
parser ||= new DOMParser();
const html = parser.parseFromString(contents, 'text/html');
const styles = Array.from(html.querySelectorAll<HTMLLinkElement>('link[rel="stylesheet"]'));
@ -62,7 +61,7 @@ async function preloadHref(link: HTMLAnchorElement) {
return fetch(el.href);
})
);
} catch {}
} catch { }
}
export interface PrefetchOptions {
@ -84,14 +83,21 @@ export default function prefetch({
selector = 'a[href][rel~="prefetch"]',
throttle = 1,
}: PrefetchOptions) {
const conn = navigator.connection;
// If the navigator is offline, it is very unlikely that a request can be made successfully
if (!navigator.onLine) {
return Promise.reject(new Error('Cannot prefetch, no network connection'));
}
if (typeof conn !== 'undefined') {
// Don't prefetch if using 2G or if Save-Data is enabled.
if (conn.saveData) {
// `Navigator.connection` is an experimental API and is not supported in every browser.
if ('connection' in navigator) {
const connection = (navigator as any).connection;
// Don't prefetch if Save-Data is enabled.
if (connection.saveData) {
return Promise.reject(new Error('Cannot prefetch, Save-Data is enabled'));
}
if (/2g/.test(conn.effectiveType)) {
// Do not prefetch if using 2G or 3G
if (/(2|3)g/.test(connection.effectiveType)) {
return Promise.reject(new Error('Cannot prefetch, network conditions are poor'));
}
}
@ -109,12 +115,8 @@ export default function prefetch({
});
requestIdleCallback(() => {
const links = Array.from(document.querySelectorAll<HTMLAnchorElement>(selector)).filter(
shouldPreload
);
for (const link of links) {
observe(link);
}
const links = [...document.querySelectorAll<HTMLAnchorElement>(selector)]
.filter(shouldPreload);
links.forEach(observe);
});
}

View file

@ -5,7 +5,7 @@ export default function (options: PrefetchOptions = {}): AstroIntegration {
return {
name: '@astrojs/prefetch',
hooks: {
'astro:config:setup': ({ updateConfig, addRenderer, injectScript }) => {
'astro:config:setup': ({ injectScript }) => {
// Inject the necessary polyfills on every page (inlined for speed).
injectScript(
'page',