Repository: hotwired/turbo (2025-07-29T12:53:00Z)

Issue:
Prefetch requests may slow down navigation
When multiple fetch requests are queued, they are likely processed one after another. For slow connections but also (temporarily slow)  servers, this can become an issue when using Turbo's prefetch feature.

Assume you are hovering over 5 menu items (long enough, that Turbo will prefetch the URL), then finally click on a link. Because other requests (pending prefetches) are still being processed, this will take a long time until its the the request of the actual link click's turn. This will unfortunately create a worse experience than without prefetching at all. 

Here are two ideas how we could improve on this:
* Cancel fetches to any pending prefetches (except the current) when clicking a link/visiting a page (AbortController).
* Executing prefetch requests with `priority: 'low'` (Fetch Priority API).



Discussion:
See #1421 for an improvement. It might still be worth to actually abort fetches in some scenarios, but that can still be done in a subsequent PR.



Patch:
diff --git a/src/observers/link_prefetch_observer.js b/src/observers/link_prefetch_observer.js
index 04c583ab1..42854f69f 100644
--- a/src/observers/link_prefetch_observer.js
+++ b/src/observers/link_prefetch_observer.js
@@ -78,6 +78,8 @@ export class LinkPrefetchObserver {
           target
         )
 
+        fetchRequest.fetchOptions.priority = "low"
+
         prefetchCache.setLater(location.toString(), fetchRequest, this.#cacheTtl)
       }
     }


Test patch:
diff --git a/src/tests/functional/link_prefetch_observer_tests.js b/src/tests/functional/link_prefetch_observer_tests.js
index c4bcd907c..b4d2132cd 100644
--- a/src/tests/functional/link_prefetch_observer_tests.js
+++ b/src/tests/functional/link_prefetch_observer_tests.js
@@ -26,6 +26,7 @@ test("it prefetches the page", async ({ page }) => {
 
   expect(url).toEqual(await link.evaluate(a => a.href))
   expect(fetchOptions.headers["X-Sec-Purpose"]).toEqual("prefetch")
+  expect(fetchOptions.priority).toEqual("low")
 
   await link.hover()
   await noNextEventOnTarget(page, "anchor_for_prefetch", "turbo:before-fetch-request")