fix: abort superseded preloads - #17080
Open
gcamargosilva wants to merge 1 commit into
Open
Conversation
When a `data-sveltekit-preload-data` preload is superseded by a preload for another link, its in-flight requests are now aborted instead of running to completion. The `AbortSignal` is threaded through `load_route` into both the `__data.json` request and the `fetch` passed to `load`. Aborting only happens while the preload is still speculative — once its token has been consumed by a real navigation, `discard_load_cache` leaves it alone so the navigation the user asked for isn't cancelled. `preloadData()` is unaffected: it passes no `AbortController`, so its requests are never cancelled by a subsequent preload. Two related fixes: - a superseded preload rejects after `load_cache` has already been replaced, so the rejection handler now only discards the cache when it still owns it - `discard_load_cache` attached no rejection handler to `load_cache.fork`, which turned every aborted preload into an unhandled rejection under `experimental.forkPreloads`
|
Install the latest version of pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/56bf4fefff27fb63918a0251d753dedc3454f51eOpen in Note This PR is from a fork. A maintainer must approve approve each commit before it can be built and installed. |
🦋 Changeset detectedLatest commit: 56bf4fe The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
gcamargosilva
marked this pull request as ready for review
September 9, 2026 16:47
| }); | ||
| } else { | ||
| void _preload_data(intent); | ||
| void _preload_data(intent, true); |
Contributor
There was a problem hiding this comment.
Suggested change
| void _preload_data(intent, true); | |
| // swallow rejections (e.g. AbortError when this preload is superseded and | |
| // its controller is aborted) so they do not surface as unhandled rejections | |
| void _preload_data(intent, true).catch(() => {}); |
In production builds, superseding an in-flight cancellable preload triggers an unhandled promise rejection (AbortError) because the non-DEV void _preload_data(intent, true) call has no .catch.
gcamargosilva
marked this pull request as draft
September 9, 2026 16:58
gcamargosilva
marked this pull request as ready for review
September 9, 2026 17:39
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
Hello guys,
I'm not sure if this is a specific edge case, but I have an Svelte app with many links where some preloads can take 1s+.
When hovering over multiple links, the previous preloads keep running even after they've been superseded. When the user clicks a link, this can make the navigation wait for those previous preloads to finish.
During the investigation, I noticed that preloads don't have an
AbortController, so I couldn't find a way to cancel these requests.Proposed fix
This PR aborts in-flight requests when a speculative preload is superseded by a newer one.
The signal is propagated through
load_routeto both the__data.jsonrequest and thefetchavailable toloadfunctions.Once a preload is consumed by a real navigation, it is no longer aborted, so user-initiated navigation remains unaffected.
I also fixed two related issues around rejected preload promises/unhandled rejections that became apparent while implementing this.
I'm not sure whether this is a broader problem or just an edge case from my application, so feel free to reject this PR if the behavior doesn't make sense for SvelteKit's preload model.
Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
Tests
pnpm testand lint the project withpnpm lintandpnpm checkdata-sveltekit-preload-data aborts a superseded preloadwas verified to fail onversion-3and pass with this change. The fulltest-basicsPlaywright suite passes (693 passed, 0 failed), as dooxfmt --check,eslint, andtsconpackages/kit(the pre-existingsrc/exports/vite/index.jsTS2321 is unrelated and also present onversion-3).Changesets
pnpm changesetand following the prompts. Changesets that add features should beminorand those that fix bugs should bepatch. Please prefix changeset messages withfeat:,fix:, orchore:.Edits