-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace data-sveltekit-prefetch
/prefetch(...)
/prefetchRoutes(...)
#7776
Conversation
🦋 Changeset detectedLatest commit: 2553a9d The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
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 |
I can hear @tcc-sejohnson's voice telling me that we need to refactor |
glad i could wheedle my way into your subconscious I'd be curious about the memory-mangement characteristics of a less-closure-y implementation as well. More efficient because the garbage collector knows what to do better? Less efficient because the runtime is smart? Honestly, I have no clue. |
Overall this change looks largely good to me, although I also have to admit that this feels like a "diminishing returns"-situation. |
The reason for
So does Agree that
Yep! You have to query the DOM, and for each And it still wouldn't completely solve the problem — if an For those links, failure to eagerly import their code isn't catastrophic — it just means that SvelteKit will automatically do it on hover or tap instead of when it first becomes visible. Given that those sorts of links are the minority, it feels like a lousy trade-off. |
When I think about the definition of the term If we want to keep |
By running the |
I just wanted to point out that it doesn't make much sense to preload on keydown, IMO. |
I totally get the reasoning for wanting to name this "preload" because of the "load" function, but in my mind that name is just much more connected with browser things. Dare we make a poll on this? |
Au contraire! When the click happens, you have about 100ms to update the screen if you want the transition to be perceived as instant. This REPL demonstrates that the gap between the Though your comment did make me realise that we're responding to
I'm honestly confused by this. |
Co-authored-by: S. Elliott Johnson <sejohnson@torchcloudconsulting.com>
I believe I have code that looked like this before:
Which will fail when running
So if i change to
Then the DOM will complain:
|
outdated code (breaking change) reference: sveltejs/kit#7776
Migration guide
Rename all occurences of
data-sveltekit-prefetch
in your code base todata-sveltekit-preload-data
:One occurence of this is most likely inside of
app.html
, if you started from the default template recently.Instead of
hover
you can now specifytap
, which will only trigger aload
when the user taps on a link.You can also now add
data-sveltekit-preload-code
, which will import all the JavaScript (and CSS, if necessary) for links. It can have the sametap
orhover
values, plusviewport
(preload links as they become visible) orpage
(preload everything on the page after each navigation).The
prefetch('/some-route')
function imported from$app/navigation
is nowpreloadData('/some-route')
:The
prefetchRoutes(['/some-route', 'some-other-route'])
function is nowpreloadCode('/some-route', '/some-other-route')
:PR description
Closes #7289.
Doing things slightly backwards here — a PR before an issue/discussion — because whether or not it's a good idea largely depends on how expensive the implementation is.
Good news: it's cheap. The changes here add 402 bytes (187 zipped) to the start bundle, which I personally think is acceptable, even if we should use that yardstick sparingly. (Will update these numbers as they change; I suspect there's room for some code golf.)
Today, any link with
data-sveltekit-prefetch
(on the element itself, or a parent) gets prefetched when you a) tap on it or b) rest the mouse over it. This is a useful feature that helps navigations feel fast, but I don't think the design is fully baked. I'd like to make some changes while we still can.navigator.connection.saveData
, which is supported in Chrome).prefetch
is a gentle hint to the browser;preload
is an instruction. In the SvelteKit context, it causesload
functions to run (which may or may not involve afetch
).data-sveltekit-preload
is thus a better name.preload vs prepare
We need to distinguish between the code and the data. It's possible (and in many cases makes sense) to get the code for a given route without getting the data. Let's call these two things
prepare
andpreload
(open to bikeshedding). Someone might want to prepare all the routes that are linked to from the current page, or within the current viewport, but want to delay loading until the user actually clicks.(They might also want to preload all those pages, but I'm not sure we should let them as it feels like a bit of a footgun. Right now, you can only preload for a specific navigation, and the promise is discarded as soon as you preload something else or navigate. We gloss over the fact that preloading makes data stale, because in practice it's fine when we're talking about a link that the mouse is already at rest over, but it would be less fine if we had the data for potentially hundreds of pages just sitting around in memory, only to discard and rebuild the cache every time we navigated.)
Personally I think I'd prefer a declarative approach to this over a programmatic one (though people can of course use the existing APIs, though more on that later). We could have options like these, in increasing order of aggressiveness:
tap
— triggered bymousedown
,touchstart
, or hitting Enter over a focused linkhover
— (current behaviour) triggered by the mouse coming to rest over a link, but alsotouchstart
or Enter on a focused linkviewport
— triggered when a link enters the viewportpage
— applies to every link that exists after a navigationSo you might have something like this...
...which would mean 'eagerly import the modules for every page I might visit next, but only load the data when I tap on the link'.
viewport
andpage
would be invalid values fordata-sveltekit-preload
. Sinceprepare
is a prerequisite forpreload
,data-sveltekit-preload="hover"
would implydata-sveltekit-prepare="hover"
if it was otherwise unset (or was set to"tap"
, which would be nonsensical).All of these should be disabled when
navigator.connection.saveData === true
, I think.Fixing the APIs
We also have two programmatic APIs for this stuff —
prefetch(href)
andprefetchRoutes(hrefs)
. If we were to renamedata-sveltekit-prefetch
todata-sveltekit-preload
then we should renameprefetch(href)
topreload(href)
.Meanwhile
prefetchRoutes(hrefs)
could becomeprepare(...hrefs)
. I don't know if we should keep the behaviour where if no arguments are supplied, it imports your entire app. Maybe?Questions
data-sveltekit-prepare
anddata-sveltekit-preload
good names?document.querySelector('a[data-sveltekit-prepare="viewport"], [data-sveltekit-prepare="viewport"] a')
inside ascroll
event listener? (Probably.)Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
Tests
pnpm test
and lint the project withpnpm lint
andpnpm check
Changesets
pnpm changeset
and following the prompts. All changesets should bepatch
until SvelteKit 1.0