mirror of
https://github.com/withastro/astro.git
synced 2025-02-17 22:44:24 -05:00
Fallback to tap prefetch strategy on slow connection (#9092)
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com>
This commit is contained in:
parent
0970fd635c
commit
0ea4bd47e0
3 changed files with 35 additions and 9 deletions
5
.changeset/neat-mangos-judge.md
Normal file
5
.changeset/neat-mangos-judge.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': minor
|
||||
---
|
||||
|
||||
Changes the fallback prefetch behavior on slow connections and when data saver mode is enabled. Instead of disabling prefetch entirely, the `tap` strategy will be used.
|
5
.changeset/six-owls-trade.md
Normal file
5
.changeset/six-owls-trade.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': minor
|
||||
---
|
||||
|
||||
Adds a `ignoreSlowConnection` option to the `prefetch()` API to prefetch even on data saver mode or slow connection.
|
|
@ -56,7 +56,7 @@ function initTapStrategy() {
|
|||
event,
|
||||
(e) => {
|
||||
if (elMatchesStrategy(e.target, 'tap')) {
|
||||
prefetch(e.target.href, { with: 'fetch' });
|
||||
prefetch(e.target.href, { with: 'fetch', ignoreSlowConnection: true });
|
||||
}
|
||||
},
|
||||
{ passive: true }
|
||||
|
@ -176,6 +176,10 @@ export interface PrefetchOptions {
|
|||
* - `'fetch'`: use `fetch()`, has higher loading priority.
|
||||
*/
|
||||
with?: 'link' | 'fetch';
|
||||
/**
|
||||
* Should prefetch even on data saver mode or slow connection. (default `false`)
|
||||
*/
|
||||
ignoreSlowConnection?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,7 +194,8 @@ export interface PrefetchOptions {
|
|||
* @param opts Additional options for prefetching.
|
||||
*/
|
||||
export function prefetch(url: string, opts?: PrefetchOptions) {
|
||||
if (!canPrefetchUrl(url)) return;
|
||||
const ignoreSlowConnection = opts?.ignoreSlowConnection ?? false;
|
||||
if (!canPrefetchUrl(url, ignoreSlowConnection)) return;
|
||||
prefetchedUrls.add(url);
|
||||
|
||||
const priority = opts?.with ?? 'link';
|
||||
|
@ -211,15 +216,11 @@ export function prefetch(url: string, opts?: PrefetchOptions) {
|
|||
}
|
||||
}
|
||||
|
||||
function canPrefetchUrl(url: string) {
|
||||
function canPrefetchUrl(url: string, ignoreSlowConnection: boolean) {
|
||||
// Skip prefetch if offline
|
||||
if (!navigator.onLine) return false;
|
||||
if ('connection' in navigator) {
|
||||
// Untyped Chrome-only feature: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection
|
||||
const conn = navigator.connection as any;
|
||||
// Skip prefetch if using data saver mode or slow connection
|
||||
if (conn.saveData || /(2|3)g/.test(conn.effectiveType)) return false;
|
||||
}
|
||||
// Skip prefetch if using data saver mode or slow connection
|
||||
if (!ignoreSlowConnection && isSlowConnection()) return false;
|
||||
// Else check if URL is within the same origin, not the current page, and not already prefetched
|
||||
try {
|
||||
const urlObj = new URL(url, location.href);
|
||||
|
@ -241,6 +242,12 @@ function elMatchesStrategy(el: EventTarget | null, strategy: string): el is HTML
|
|||
if (attrValue === 'false') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fallback to tap strategy if using data saver mode or slow connection
|
||||
if (strategy === 'tap' && (attrValue != null || prefetchAll) && isSlowConnection()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If anchor has no dataset but we want to prefetch all, or has dataset but no value,
|
||||
// check against fallback default strategy
|
||||
if ((attrValue == null && prefetchAll) || attrValue === '') {
|
||||
|
@ -254,6 +261,15 @@ function elMatchesStrategy(el: EventTarget | null, strategy: string): el is HTML
|
|||
return false;
|
||||
}
|
||||
|
||||
function isSlowConnection() {
|
||||
if ('connection' in navigator) {
|
||||
// Untyped Chrome-only feature: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/connection
|
||||
const conn = navigator.connection as any;
|
||||
return conn.saveData || /(2|3)g/.test(conn.effectiveType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen to page loads and handle Astro's View Transition specific events
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue