Svelte implements event delegation by attaching a single event listener to the root element and using the composedPath property to determine which handlers to execute, significantly improving performance when handling many interactive elements. The framework also enhanced async rendering by correctly identifying dependencies in template expressions and adding promise blockers to prevent reading data before it resolves, ensuring components render only after awaited values are available.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
This Week in Svelte, Ep. 142 — ChangelogAdded:
[music] [music] [music] [music] [music] [music] [music] >> Welcome everyone to this week's Svelte episode 142.
I can't keep track.
Uh today is an earlier episode because we have continuous meeting later.
Uh so yeah, let's jump right into it.
Uh and let's see. We have a pretty like ginormous release.
Uh which it's it's a thing.
Uh let's start. So, unlink, errored, and otherwise finished batch. So, obviously so um the batches are uh a linked list. So, yeah, like you will actually use linked list in your day-to-day job.
Uh but yeah, basically if those uh batches, which again is the primitive, like the data structure that Svelte is using under the hood to keep track of when you have multiple sources of asynchronous data that start in parallel and they can interleave in certain ways, a batch is a single change of this basically. And so if they are errored or finished, they are unlinked.
Perform walk composed by directly in delegated event propagation. So delegated event propagation it's a very nice technique that's about it's using.
Let's say let me do this very quickly.
Let's say that you have something like this. I don't know. Your app can have I don't know, a thousand elements and each one, sorry, I lost something but it's fine. I'll I'll get it later.
Your app can have a thousand elements, right? And each element can have its own click handler for example. So let's say that you have a bunch of click handlers.
It is way more heavy in terms of it's not at least more is less performant but is also heavier in in terms of memory to actually add an event listener on all the buttons. However, the event propagation techniques is something that you can actually use yourself if you ever find yourself in a such a situation. But it basically takes advantage of the fact that when the like the events the click events and stuff like that bubble in the dome. So let's say that you have I don't know.
Let's say that you have each button like each array a hundred and this each has a bunch of buttons, right?
And let's actually make it nicer, just the top to nicer.
Uh you have a bunch of buttons and I mean, let's say that you have I don't know.
Let's do this and let's show the the number of the button.
plus one and the number of the button. Actually, I'm I'm always lost in these details, but let's do dot to string dot pad left two zero. Not pad left.
Uh let me like pad left should be something. No?
pad start ah pad start. So, that they all have to to thing and let's style it so that uh div is display grid and grid template columns is repeat 10 I don't know. 10 px Ah, that is too much. 1fr is fine.
and grid template I guess I can not do it.
rows 1fr Yeah, I can pretend doing it.
And let's say that a button is aspect ratio of one.
Yeah.
And I don't know. width Yeah, let's do it like this. I mean, it is super silly and I don't know why I'm spending time making something nicer.
Um But, yeah.
We have our grid of buttons that we can click now. Now, what we could do is that we could say like on click and then on each element add an event listener to console.log I don't know, I for example, right? So, you can technically do this, and this will mean that whenever you click on something, you get the number that you clicked on, right? That's very nice and easy. However, uh it's a bit heavy in terms of memory because you are creating a new function every time, you are assigning an event listener, and in general, the process of adding an event listener, it is something that is a bit heavy both in terms of performance and in terms of um in terms of um you get it. Uh let's say that we do data I for example, then we do I, right?
Now, what we can do is that we can move the on click to the div. You will need to Svelte ignore uh this warning because uh no static interaction.
And I guess I think.
Why isn't it working?
Regardless, yeah, okay.
Ah, because I'm on I'm a super silly guy.
Yeah.
So, you you need to Svelte ignore this, but now, despite the fact that we have the on:click just on the div, when I click on the button, you can see I mean, in this case, I is not defined, but I can do A, and I can do A.dataset.i.
Um is the dataset.
No?
Oh, A.the target.dataset.i.
Yeah.
And as you can see, like, we got pretty much the same result, but now we only have one single listener. So, we don't have to add a listener for each button. Basically, Svelte does the same thing for every event in your application. So, we add a single listener to the root of your application, and then when something bubbles up, I mean, we have to do a bit of trickery, like we need to store the information about which handlers needs to be called.
We need to do like, there's a bunch of stuff to be done to do it properly.
Like, the delegate event delegation is a pretty chunky event.
Uh and one of the things is that we need to uh use this composed path. The composed path property like function on an event basically takes like, it returns you the list of all the elements that are part of the click handler. I just I really closed it, but let me show you.
Uh if we do it once again, so let's say that once again I have a div, and I have a button like this. Click.
And I do on:click here.
And I do E and I do console.log e.composedPath like this.
It should be on the event if I'm not mistaken. We'll see.
Uh basically, what this does is that when you click, it will show you all the elements, let me zoom in a bit, that are part of this click. So, like you are clicking on the button in this case, but as you can see, like you're clicking on a bunch of stuff actually.
You're clicking on the button, but you're also clicking on the div that contains Oh, come on.
On the div that contains the button, and you're also clicking on the body that contains the div that contains the button, and on the HTML that contains the body that contains the div that contains the button, and on the document that contains the HTML, and on the window that that my father bought I mean, we have a song in Italy that uh looks like this. So, uh we read the composed path to figure out if the whole path like at which point of the path we are because we also need to run all the handler of the outside element. Um and there is there was this like perf and now this is worked directly.
Instead, if I'm not mistaken, before it was kind of invoking multiple time invoked multiple time to figure out. So, now it's a perf uh win.
Fix transfer effect when merging branches batches. So, when two batches are merged together, which I think it's a new thing. I don't think it um So, Uh, this is an interesting bit. Like does Svelte let us attach the native event delegation somehow instead of the centralized version? Uh, you can't do it. Like, you can't explicitly, opt out of that. You technically can because on colon click, like if you use on colon click, this will not uh event the do event delegation.
Another option is just do add attach node and then manually doing node add event listener, click and stuff like that. So, like, obviously, if you add it like this, that that will be uh a normal event. That said, it's actually something that you should pay attention to do, too, because uh opting out of the event delegation of Svelte means that sometimes the order the events gets called is not the right one, and that's why you also have import on from uh Svelte uh events.
And you can use on to actually opt in to the event delegation. So, instead of if you have a node handler, instead of opting out, you can do on node click, and then you pass the handler, and this will basically make sure that this will basically make sure that uh you are actually uh participating in the uh in the event delegation, even if you, like, registered programmatically.
So, there are ways around if you really really need, but is not recommended.
Uh allow derived await in disconnected effect roots. That's nice.
So, uh an effect root is basically the root of all the tree of the effects that runs in your application and I I at some point like they become disconnected and now you can also use derived await if they are disconnected.
I'm pretty sure that this is some like if we open this this is probably something about some clean up.
Yeah, can't access property.
Yeah, okay.
So, let's see the the actual reproduction.
If you are creating Yeah, okay. So, basically if you are creating your own effect root to do something, then it was not possible to use await inside and now it is.
Remove temporary raw text hydration marker.
Oh, that's interesting.
Okay, that's interesting.
Uh so, if you want to use feed inline styles, now you can with felt. Propagate async const blockers through closer reference so template expression like host correctly wait for the awaited value. So once again, basically, if you take a look at the compiled code of Svelte, let's actually do it very quickly.
So that should we should have a reproduction. So if you have something like this, um it will blow up during client-side rendering because it tries to read data before it even exists. So uh if you take a look at the uh compiled code, and let's say that you have if true {slash} {if} If we take a look at the compiled code, unexpected block closing tag.
Why?
What?
Whoa, there's actually I think we there's a bug in the parser.
Or maybe I don't know because it's a an open P.
So we have closing P.
So basically, if you try to do something like this, uh in the JS output, you can see that basically, we create data and then we don't actually await foo. We just create this promise here that then we calculate the things that need that promise. So in this case, we know that this template effect, which is basically this part of the code here, needs to wait for data.
And if we switch back to 5.9, you will see that this template effect basically has no blockers. So, like it looks at this expression and says, "Okay, you are not like you don't need any variable that it's awaiting because like it didn't go through the closure. So, like it didn't read also these. It just stopped at the first level here and said, "Okay, you don't need anything. You can go ahead and start rendering while we wait for this."
And so, this was causing a problem because it was trying to read data before it was actually like it was not actually waiting for data. Uh now that you have 10, you can see how it changes here. Uh there is this promises zero here, which is basically telling, "Hey, this thing needs to wait until these resolve to actually uh complete like to actually render. Otherwise, it will uh blow up."
And all of this is done so that if you have an await in the template or if you have an await in the script tag, and then you are rendering a component, the component can render if that component does not depend on the on the awaited data, it can start rendering before um before the data stops so that we don't create um a waterfall.
Um properly unlink batches. Once again, like unlinking, like removing batches from from the link list. Settle this card batches. So, even if a batch is discarded, we settle it, so like we complete the promise that is the batch.
Declare let directive before const declaration on slotted elements. So, this is a blast from the past in Svelte 4 because in Svelte 4, if you remember, you could add let this and those needs to be before const because scope-wise, you can read a let variable inside a const declaration.
Uh resume outred branches if they were kept around.
So, if a branch was outred, so like it like the outro transition was removed. If it is still around and maybe you are switching back, they can be resumed.
Avoid waterfall warning when a sync resolve to the same value. Oh, that's interesting. That's I want to take a look at this. So, there is an async waterfall.
Um Yeah.
Basically, the bug was that if you were awaiting Uh if you had something like this, I think this was giving a bunch of So, if we switch back to 0.9, I think this was Yeah. After the first time, every time you got um you got a an async waterfall. And this basically is an async derived and reactive was not read immediately after it resolved. This often indicates unnecessary waterfall, which can slow down your application. Now, the reason why we have these is because if you have an await, let's say that you are awaiting on two things, right? So, you have a wait fetch some data and await fetch some other data, right? So, let's say I mean, this will blow up, but let's say that you have like data one data two, right? And you have await fetch count, await fetch count two, right? You have these two and you are awaiting. Now, given how Svelte works, it will try to make sure that these runs in parallel anyway, but there's some situation like where you can actually read data one, which in this case fails, and then like like the point is if you write code like this, even if those two are not dependent on one another, you are introducing a waterfall, right?
Like you are awaiting here and then you are awaiting here.
Now, when you do stuff like this, we warn you to say, "Please try to not do this because this will slow down your application. You don't want an async waterfall in your code."
And [snorts] the the way we do it is that if you have a value like this, we check if the the derived is immediately read after this um after this value resolve. So, if the value resolve if you are never reading the derived, it will never fire because you never actually read it.
So, this means that this never actually execute. But, if you do read the derived, this will execute and then it will be immediately read because the reason why it was executed is because you are reading it.
The reason why it can happen that it's not read immediately is if you have another derived with another await.
And so, this means that you have a possible waterfall because those two start sequentially instead of in parallel.
Now, so we were reading this. The problem is that if a derived has the same value it will not be read once again. And so, the reason why it was throwing all these errors is because the first time it increased to one, the second time is still one, the third time is still one, the fourth time is still one. So, this derived will not actually be read again because it's the same value and Svelte does not read the same value.
And so, it was erroring out. But, after this fix, it will not actually do it.
Correctly coordinate component level effect inside a sync block. I think I think this is an important bit.
>> Okay, so this basically means that like we were checking this reaction run to determine if we can defer a top level effect.
And if it is, like basically um there were some effects that were deferred despite not uh like not needed to be deferred. And the reason was that this reaction run can be initialized in the component if it's inside an async block.
And so now it is working correctly. Um make unnecessary commit work less likely.
So um commit, this is not a git commit, is a commit of a batch. So when you when you have a batch, which once again is the data structure that we use, after that batch finish, it's committed. So when you commit, it's actually added to the DOM. Uh and sometimes it was like it could have been over fired and now not anymore.
Add the tag name to alley click event have keys event warning. This is a a small chore, but means that the error will be better now.
Catch rejected promises while merging / committing.
So yeah, if a promise is rejected, they need to be caught, otherwise while merging or committing, you would get an actual error in your application, which is not what you want.
Let's see, we have two new releases of SvelteKit.
And we have a breaking change for So we have a pretty big release of uh SvelteKit.
And we start with breaking the run method has been removed from remote queries on both the client and the server. Use await query directly, it now works everywhere. So, before, if you remember, we introduced this run method because for a period of time, you could not read a query directly, like you could not await query. So, if you wanted to read to do await query inside a non-reactive context, you had to use dot run. So, let's say that you are in an event listener and you want to get the information, you had to use dot run.
Now, we actually fixed the problem, so we are back at the nicer way of doing this, but it is obviously a breaking change for the experimental branch of the remote function.
Remote queries can now be awaited in any context.
Not just inside reactive. The cache is shared across reactive and non-reactive subscribers, so awaiting a query in an event handler will dedupe with components that have already subscribed to the same query.
Fit live query instances are now themselves async iterable.
That's nice.
So, this means that if you have a live query, you can actually await for await them.
Add programmatic submit method to form remote function instances. So, you can actually submit the form programmatically, so you can do my form.submit, and that will trigger the submission.
Fit pass form remote function into announce callback. So, you can actually get Oh, that's nice.
So, you actually get the form remote function inside the announce callback, so you don't have to import them. If you want to have an abstraction with a component, that's nice.
Resolve the app payload without using process.env.no no node env.
Okay.
Support extract optional property types for optional root params.
Exact optional property types for optional root params.
I feel like this is something for TypeScript.
Let's see.
In root params, optional root parameters type as param string, this does not work well when using exact optional property types. Seems TypeScript will yell if you pass undefined. Okay, that's nice. So, basically this is typed as param string, but with this optional, you actually need to specify and like you cannot pass undefined to this. You need to omit the uh the parameter altogether, and now you can actually use it.
Correctly send the true value to the server for submit and hidden form field.
That's correct. That's nice.
Uh avoid build warnings about undefined universal hook, which is the hook that runs both on the server and the client.
Prefer default error page when failing to decode the URL path name.
That's nice. So, instead of a generic error page, it will uh do Disable link prefetching on slow internet connection. That's actually nice. So, if you have a slow internet connection, now SvelteKit automatically disable link prefetching because obviously it can uh like mm like it can make I mean, it will make you waste more more band more bandwidth.
Allow routes handling with optional parameters next to more specific route.
So, if there is an an optional parameter and then there is a a route that is more specific like it has an actual last parameter. Now it's allowed before it was airing out.
Remove reliance on content length header in the serialized binary form which cause failure with proxies Vercel Azure.
When proxies Vercel or Azure strip the header and use chunked transfer encoding. So, uh if you remember like when you are uploading a file in in a form remote function form, we actually uh and by we I mean mostly automated which was like a big uh like it did a big contribution. Uh created basically uh its own like way like protocol to send the file which had all the information about uh the rest of the form at the beginning so that it could be validated very quickly without unpacking the whole file. Um and it was relying on content length. However, some proxies like sometimes when you go through a a proxy they will actually remove the header.
And so now uh I guess we use chunk transfer encoding.
So, then there is a regression when routes starting and ending with a route group are not matched correctly.
Let's say we have a new release of ESLint plugin Svelte.
Add no nested style style tag which is nice, I guess.
Prefer derived over derived.by.
Yeah, I guess that's a nice rule.
I want to see it more.
Like as a new rule that supports unnecessary derived by when derived is sufficient without a fix. The rule flags derived by calls whose argument is a zero parameter known as sync known generator function that either uses a concise arrow body or uses a block containing only a single return statement.
Or function. Multi-statement bodies are left untouched because removing the wrapping function would change the semantic. Okay. So, yeah, effectively this is just like it's a nice thing if you have if you do some stuff like this or stuff like this, it will now yell at you ESLint. So, that's nice.
Fit, no navigation without resolve recognizing nullish TypeScript type as allowed. So, if you have a nullish type, it's also allowed I assume inside uh the parameters.
And that's actually it.
So, that was uh like a quick one today.
Not much uh not not many releases, but uh it was a nice one. Like two very big releases for Svelte and SvelteKit.
Uh so, yeah.
That's it. Thank you everyone for joining in. Thank you everyone for watching.
Um I'm pretty sure, let me check. I can't remember uh I I think I I will be here next Friday.
There are some uh Yeah, you are seeing my calendar.
Uh yeah.
There are Yeah, next Friday I should be here.
Um The Friday after I I will not be here.
So, next Friday, see you next Friday.
Bye.
>> [music] [music]
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 views•2026-05-29
🚀 BCS613C Compiler Design | Module 1 to 5 Schema Evaluation 🔥 | VTU 6th Sem 💯 #VTU #bcs613c #exam
Pranavaa-y4y
104 views•2026-06-02











