DEV Community

Cover image for 💡Imagine Svelte with Virtual DOM: A Vision for the Future of Web Frameworks
Rajaniraiyn R
Rajaniraiyn R

Posted on

💡Imagine Svelte with Virtual DOM: A Vision for the Future of Web Frameworks

👋 Hey there! Welcome to the exciting world of web development! Today, we're going to explore a fascinating concept that is revolutionizing the way we build web applications. So buckle up, and let's dive in!

Svelte is one of the most popular frontend frameworks, loved by developers and created by journalist Rich Harris. However, its approach to reactivity and stance on Virtual DOM (VDOM) has always been a topic of discussion when compared to rivals React and Vue.

While Svelte's approach makes sense, there are situations where the absence of VDOM can be limiting. This is where a new thought experiment comes in: a hybrid of Svelte and VDOM.

But before we delve into the thought experiment, let's take a closer look at what VDOM is and Svelte's no VDOM approach.

I have no idea

What is VDOM?

A virtual DOM is a copy of the real DOM that exists in memory, not on the screen. When making changes to the real DOM, it can be slow and inefficient. On the other hand, changing the virtual DOM is much faster and easier. By using a virtual DOM, you can make changes to the virtual copy first, and then compare it to the real DOM to find the differences. These differences are called patches, which can then be applied to the real DOM to avoid unnecessary repaints and reflows.

Frameworks like React and Vue use virtual DOMs to make websites more responsive and performant. They handle the creation and updating of the virtual DOM for you. However, Svelte takes a different approach and doesn't use a virtual DOM. Instead, Svelte compiles your code into highly optimized vanilla JavaScript, updating the DOM directly without the overhead of a virtual DOM.

Svelte's no VDOM Architecture

Svelte, one of the most loved frontend frameworks, is different from its rivals React and Vue in that it doesn't use a virtual DOM. While virtual DOM allows faster and smoother updates, it requires two copies of the DOM and complex comparisons. Svelte takes a unique approach by compiling code into small JavaScript modules that directly update the real DOM. It analyzes the code at compile time to know exactly what needs to change, making your website faster and smaller. Svelte's special syntax makes code reactive, automatically responding to changes in data or state.

Advantages of No VDOM

One of the major advantages of Svelte's no virtual DOM architecture is speed. By eliminating the need to create and update two copies of the DOM and compare the differences, Svelte can be faster and simpler than using a virtual DOM. It also results in a smaller bundle size, as fewer or no frameworks or libraries need to be loaded, which in turn improves the loading time and bandwidth consumption of web applications.

Svelte's no virtual DOM architecture also gives developers more control and flexibility over how they update the real DOM. They can use direct manipulation, data binding, templating, or any technique that suits their needs.

Disadvantages of No VDOM

However, the lack of virtual DOM architecture means more responsibility and complexity for developers. This includes managing and optimizing real DOM updates, addressing performance issues, memory management, event handling, and cross-browser compatibility. This can lead to less abstraction and convenience for developers, who may need to write more code or use more tools to achieve the same results without the benefits of a framework or library.

Another disadvantage is that when updating the real DOM directly, developers must manually synchronize the data and the UI to avoid inconsistencies. Although this applies to any approach that updates the real DOM directly, not just Svelte.

Why do we need VDOM in Svelte?

There are both advantages and disadvantages to using VDOM in Svelte, as we discussed earlier. However, having an option to enable VDOM in Svelte can provide some benefits to developers and professionals who require more advanced features or better performance in certain scenarios.

For example, enabling VDOM in Svelte can allow developers to use VDOM-based libraries like React Framer Motion for advanced animations or other VDOM-based libraries for other features that Svelte may not support natively. This can provide more flexibility and options for developers to build more complex applications with Svelte.
Framer Motion Animations
Additionally, enabling VDOM in Svelte can improve performance in certain scenarios, such as when dealing with large feeds or SPAs with multiple DOM operations. This can help Svelte remain competitive with other VDOM-based frameworks in terms of performance and scalability.

However, enabling VDOM in Svelte also comes with its own set of trade-offs, such as increased complexity and potential inconsistencies between the virtual and actual DOM. Developers would need to weigh the benefits and drawbacks of enabling VDOM in Svelte and decide if it's worth the added complexity and potential issues.

Hypothetical VDOM in Svelte

What the hell

These issues have been faced by many Svelte developers at some point during their development journey. While Svelte's performance is exceptional, there are some shortcomings that become more apparent with long-term use.

What if Svelte had a virtual DOM that could be optionally enabled by developers at the component level?
For example:

<svelte:option vdom />

<script lang="ts">
export let count: number = 0;
</script>

<button>
{#if count > 0}
Clicked {count} times
{:else}
Click me!
{/if}
</button>
Enter fullscreen mode Exit fullscreen mode

In the example above, the svelte:option tag includes a vdom attribute that takes a boolean value and enables VDOM specifically for that component.

The Example we seen so far is relatively straight-forward to implement in the svelte repo as well. To use VDOM libraries such as Million.js or Hyper DOM with Svelte, the helper functions used by Svelte for DOM manipulations would need to be updated. With VDOM enabled, a virtual DOM would be created instead of a regular DOM. Whenever a component changes, the virtual DOM could be updated using the VDOM libraries, and then mounted. This approach would allow developers to avoid touching the actual DOM, which could lead to significant performance gains, particularly in cases where multiple DOM operations are required.

Example Implementation

Most of the DOM manipulating is done from a single file - svelte/src/runtime/internal/dom.ts we can just port this 757 loc (as of writing) to use some VDOM libraries or custom VDOM implementation. For example,
below is the code from the svelte dom.ts file

export function append(target: Node, node: Node) {
    target.appendChild(node);
}
Enter fullscreen mode Exit fullscreen mode

we can change this to something like this

export function append(target: Node, vnode:(props) => VNode) {
    const block = block(vnode)
    mount(block, target)
}
Enter fullscreen mode Exit fullscreen mode

in the above example we have just changed the direct DOM manipulation with Million.js virtual DOM implementation APIs.

Similarly, we can port all the functions for VDOM and conditionally enable it. That's it we implemented new feature in svelte.

is that it?

Svelte is a powerful and efficient framework that has gained popularity in recent years. Recently, the Svelte team announced their plans for the upcoming versions 4 and 5. While there won't be any major breaking changes, the framework will continue to evolve and improve.

Optional VDOM is just an imaginary feature that will make the svelte even more awesome and cool. Even we can make use of dynamic imports (lazy imports) of VDOM so we can reduce initial javascript bundle size.

What will happen if this lands in Svelte?

Mind Blowing

Svelte's success does not mean that other frameworks will fall by the wayside. In fact, the frontend framework landscape is constantly changing, with new frameworks emerging all the time. Each framework has its own strengths and weaknesses, and developers must choose the right tool for their specific needs.

React, for example, is a highly popular framework that has a large community and a vast ecosystem of libraries and tools. Vue, on the other hand, is known for its ease of use and has gained popularity all over the world. Angular is a robust and comprehensive framework that is ideal for building large-scale applications. Ember, Solid, Astro, Qwik, Marko, Lit, and many others all have their own unique selling points and strengths.

Ultimately, the choice of framework depends on various factors, including the project requirements, the team's expertise, and personal preferences. While Svelte may not be the ultimate frontend framework, its unique approach and innovative features have certainly made it a popular choice among developers.

Conclusion

Finally, We are waking up from the thought experiment, Svelte may or may not be good but it is a good framework to start web development journey. Hybrid of svelte and vdom may be nothing as of now, but it may be a thing in the future. May be another framework could arise based on svelte with vdom.


If you found this post informative and useful, be sure to follow for more content like this to enhance your web development skills and stay up-to-date with the latest trends and technologies in the field.

Top comments (16)

Collapse
 
miketalbot profile image
Mike Talbot ⭐

Can you help me understand something in this? I can't quite envisage a scenario where in Svelte the same property of a DOM object is changed more than once as a result of some atomic operation - i.e. during the same event. As I can't think what this would be, my initial reaction is that a VDOM is going to be a big overhead. If I update the VDOM it still has to be synched to the DOM, so the DOM write is going to happen anyway.

Can you give me an example of where you would be updating the same DOM property multiple times? I guess if it was stopping a case where the same value was being written back then I'd understand it, but I don't think that's a common case.

Collapse
 
rajaniraiyn profile image
Rajaniraiyn R

Hello, thank you for your comment. I’m happy you are interested in Svelte and how it compares to other frameworks. Svelte does not use a VDOM because it creates JavaScript code that directly updates the DOM. This way, it ensures that only the necessary updates are made and nothing more. A scenario where a VDOM would prevent multiple updates to the same property is when you have a list of items that can be sorted or filtered by different criteria. In that case, a VDOM would enable you to update the order or visibility of the items in the VDOM first, and then apply the changes to the DOM in one go. Another example is when you have a complex UI with many nested components that depend on each other’s state. If you use a VDOM, you can update the state of one component and let the VDOM handle the propagation of the changes to the other components. This way, you avoid manually updating each component and triggering multiple reflows and repaints in the browser. I hope this explains your question 😊

Collapse
 
miketalbot profile image
Mike Talbot ⭐

Thanks, I've multiple projects live using Svelte, Vue and React so I understand both the reactive vaniallaJS and the VDOM models. I'm still struggling a little with your example, in Svelte if I had a list then I could key that list, it would still only write to the DOM elements that changed, and it would only write the changed properties, append or remove from the list etc. I'm not getting how a VDOM is anything except overhead, sure you'd change those properties on something that didn't cause a reflow, but then synchronisation would cause a reflow. Are you suggesting that Svelte changing 4 properties as part of an atomic interaction would cause more reflows than the VDOM sync? That wasn't my understanding.

Thread Thread
 
rajaniraiyn profile image
Rajaniraiyn R • Edited

Actually in svelte reactivity on Arrays and Objects are bit different. The DOM updates are triggered on the basis of variable assignment not by the individual mutations. For example, I have a list of students in a class with their scores. I store the data as array and iterate through that data and display the UI in svelte. after rendering to the DOM if I add(push) some other student it won't update the DOM reactively. If you want to achieve reactivity then you have to reassign that array with this newly updated one which results in the unnecessary re-rendering of the entire list. This won't be much for a list of 50 students or something. But definitely a worst-case if we have hundreds and thousands of students. But if the same thing is done with VDOM. we will update the entire list of students in the VDOM first, then with the help of DOM-Diffing we will only update the minimal possible DOM mutations to apply the change.
@efpage This would be a convincing example.
Reference: learn.svelte.dev/tutorial/updating...

Thread Thread
 
miketalbot profile image
Mike Talbot ⭐ • Edited

Are you sure, what about this: svelte.dev/tutorial/keyed-each-blocks? I believe it's being smart enough here not to regenerate the entire list, but to only affect the elements.

To test this I used the example above and modified the code so it uses thing.id as a key. I then used Dev tools to set a random property on the last dom element (in my case I set a property called testing to be equal to banana. I then clicked the button to remove the first element, regenerating the list, and confirmed that my property still existed, demonstrating that Svelte is not regenerating the entire DOM.

Thread Thread
 
rajaniraiyn profile image
Rajaniraiyn R

Your point it correct. we can use keyed each block for these kind of issues. I tested this method but the problem with this way is if we have multiple mutations in a single list there is a high chance for key collisions. When i was trying with the REPL it throw errors. in that case I think VDOM does better job than svelte. That is because of the maturity of VDOM libraries is much more vast than svelte at this point

Thread Thread
 
neeh profile image
neeh • Edited

if we have multiple mutations in a single list there is a high chance for key collisions

I don't follow you here, do you mind sharing your REPL example?
If keyed each can't handle multiple mutation then it's a bug that should be fixed.

Collapse
 
efpage profile image
Eckehard

The VDom was created to make life simpler. You just describe the new state of te UI and the VDom manages the state changes. Managing state transitions may be challenging, especially for larger apps tha are created by big teams.

But this does not mean, a VDom is faster. Dom-diffing may take a lot of ressources, and you need to build you UI in a way, that each element can be identified. Otherwise the VDom does not know, if an element was changed or not.

Svelte uses a compiler to implement the routines that manage the state changes. So you get the same comfort with less tradeoff. Implementing a VDom for Svelte is like you have a sportscar and want to have the option to pull it with a horse...

Collapse
 
rajaniraiyn profile image
Rajaniraiyn R

Thank you for your comment. I agree that the VDOM has some drawbacks and that Svelte has some advantages over it. However, I think that the VDOM is more compatible with other libraries and frameworks. For example, if we have DOM diffing we can easily and efficiently achieve SPA Page(View) transitions like

, similarly we many more example where VDOM slightly outperforms svelte.
Could you please share your thoughts on these aspects?
Collapse
 
efpage profile image
Eckehard

We schould first talk about the task to solve. Should we stop riding bikes because cars are faster?

Thread Thread
 
rajaniraiyn profile image
Rajaniraiyn R

Yeah. I am agreeing with you. This is only optimal for very rare and specific use cases. Thats why this post is on optional VDOM, not disturbing the actual svelte mottos, but enables developers to enjoy the features of VDOM as well.
Definitely we can't stop using 2-wheelers or 4-wheelers for each others best. But in this world they co-exists and even there are some 3-wheelers too.

Collapse
 
rajaniraiyn profile image
Rajaniraiyn R

According to svelte.dev, Objects and Arrays will trigger reactivity only if reassignment rather than mutations happen on them.
Say we are building Twitter, we will have all of our tweets as an array of tweets where each of the tweets will be an object having data like content, impressions_count , likes_count, retweet_count, comments_count, author, id. Among those data, impressions_count, retweet_count, likes_count and comments_count are changing in realtime. Since they are stored as an object and the changes are received as objects only, consider what happens after initial rendering. We have to update the likes_count. Since we cant update the like count alone, we have to re-render the entire tweets as the tweet object is within the array. This makes svelte more inefficient even though it is more performant and capable. If we use VDOM within svelte, its too obvious that even if we re-render everything in VDOM (more cheaper operation) in the actual DOM only the likes_count of that particular tweet will be changed. Yeah, same can be achieved in svelte too but we have to use more complex approach on state management and our implementation.
I hope this would help and makes things more clear.

@miketalbot This example will also suits well

Collapse
 
efpage profile image
Eckehard • Edited

If you read the post from Rich-Harris: The truth about Svelte, incrementally adopting Svelte into your existing ecosystem should be possible. I´m not sure about React, but in theory, adopting VUE incrementally should be possible also. Running both in the same application should be possible. So, if your target is to use existing libraries, this should be possible too.

If your target ist do do more efficient state managent, then maybe you should try this on a higher level to prevent unnecessary rerendering. The browser can easily handle a single element update, so your task is siply to prevent your app from doing unneceesary things on the DOM.

Thread Thread
 
rajaniraiyn profile image
Rajaniraiyn R

Yes, We can use many frontend frameworks and libraries in a same app. we have astro and incase of react and svelte we have github.com/Rich-Harris/react-svelte But the concern with this approach is that if we have to tangle between each of their concepts. like we have concepts like composition in vue which doesn't in svelte or react. this might increase the developer complexity.

Thats the problem if it is baked into the svelte itself then we can make use of svelte's conciseness without many tradeoffs. Again, this is just an imagination not an actual proposal for svelte's proposal.

Collapse
 
vitto32 profile image
Vittorio

If you want to achieve reactivity then you have to reassign that array with this newly updated one which results in the unnecessary re-rendering of the entire list.

You are not re-rendering the entire array, the equal sign is needed to trigger reactivity because the compiler looks for equal signs but that doesn’t mean a new array is created

Collapse
 
rajaniraiyn profile image
Rajaniraiyn R

Yeah you were correct but in few edge cases we use keyed each statements, which is not effective enough to handle key collisions in case of heavy mutations on arrays and objects.