diff options
author | 2023-11-22 18:40:09 +0530 | |
---|---|---|
committer | 2023-11-22 21:10:09 +0800 | |
commit | 0ea4bd47e0d7cc98c43568a55aa87da772bd2e0a (patch) | |
tree | 298b1c2a784e3763c8813a14243070b9b463ac68 | |
parent | 0970fd635c8ec59b4990dd0fd2d07fd2b937a766 (diff) | |
download | astro-0ea4bd47e0d7cc98c43568a55aa87da772bd2e0a.tar.gz astro-0ea4bd47e0d7cc98c43568a55aa87da772bd2e0a.tar.zst astro-0ea4bd47e0d7cc98c43568a55aa87da772bd2e0a.zip |
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>
-rw-r--r-- | .changeset/neat-mangos-judge.md | 5 | ||||
-rw-r--r-- | .changeset/six-owls-trade.md | 5 | ||||
-rw-r--r-- | packages/astro/src/prefetch/index.ts | 34 |
3 files changed, 35 insertions, 9 deletions
diff --git a/.changeset/neat-mangos-judge.md b/.changeset/neat-mangos-judge.md new file mode 100644 index 000000000..f42417d4a --- /dev/null +++ b/.changeset/neat-mangos-judge.md @@ -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. diff --git a/.changeset/six-owls-trade.md b/.changeset/six-owls-trade.md new file mode 100644 index 000000000..cd16cecec --- /dev/null +++ b/.changeset/six-owls-trade.md @@ -0,0 +1,5 @@ +--- +'astro': minor +--- + +Adds a `ignoreSlowConnection` option to the `prefetch()` API to prefetch even on data saver mode or slow connection. diff --git a/packages/astro/src/prefetch/index.ts b/packages/astro/src/prefetch/index.ts index f47cff060..573efe573 100644 --- a/packages/astro/src/prefetch/index.ts +++ b/packages/astro/src/prefetch/index.ts @@ -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 */ |