# Could updating the DOM directly instead of the virtual dom get any advantage for elm? (the way it does for svelte)

**URL:** <https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995>\
**Category:** Learn\
**Created:** [July 15, 2019, 8:25pm UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995 "2019-07-15T20:25:15Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![stefanr0sca](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/stefanr0sca/32/2898_2.png) [@stefanr0sca](https://discourse.elm-lang.org/u/stefanr0sca)\
**Post date:** [July 15, 2019, 8:25pm UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/1 "2019-07-15T20:25:15Z")

</div>

I am trying to understand more how that would work / why it won’t.

---

<div class="post-metadata">

**Author:** ![dmy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dmy/32/702_2.png) [@dmy](https://discourse.elm-lang.org/u/dmy)\
**Post date:** [July 16, 2019, 12:07pm UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/2 "2019-07-16T12:07:10Z")

</div>

Is this similar to [http://imba.io/](http://imba.io/)?

If so, there has been a discussion there:

> [@An alternative to virtual DOM \< 20x faster!](https://discourse.elm-lang.org/t/an-alternative-to-virtual-dom-20x-faster/2264):
>
> Hello guys, Have anyone checked [Imba](http://imba.io/)? It’s a very interesting programming language that compiles to Javascript. It uses a technique that’s explained [here](http://imba.io/guides/advanced/performance#performance) and in this [screencast](https://scrimba.com/p/c6B9rAM) which they call imperative DOM even though you write declarative code. The concept itself is pretty simple, and[this DOM reconciler benchmark](https://somebee.github.io/dom-reconciler-bench/index.html) (yes, it was written by the writer of Imba) gives very interesting results. Also try editing the number of todos in the top left and for 60 todos, Imba is 40x times faster than R…

---

<div class="post-metadata">

**Author:** ![stefanr0sca](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/stefanr0sca/32/2898_2.png) [@stefanr0sca](https://discourse.elm-lang.org/u/stefanr0sca)\
**Post date:** [July 16, 2019, 12:56pm UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/3 "2019-07-16T12:56:13Z")

</div>

Thanks for linking to the discussion. There might be a bit of similarity in the way imba targets the dom.

---

<div class="post-metadata">

**Author:** ![Laurent](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/laurent/32/2051_2.png) [@Laurent](https://discourse.elm-lang.org/u/Laurent)\
**Post date:** [July 17, 2019, 2:14pm UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/4 "2019-07-17T14:14:52Z")

</div>

Rich Harris (the creator of Svelte) said that [“Svelte is a _language_ to describe reactive user interfaces, just like Elm, Imba and a few others…”](https://gist.github.com/Rich-Harris/0f910048478c2a6505d1c32185b61934)

---

<div class="post-metadata">

**Author:** ![stefanr0sca](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/stefanr0sca/32/2898_2.png) [@stefanr0sca](https://discourse.elm-lang.org/u/stefanr0sca)\
**Post date:** [July 17, 2019, 2:45pm UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/5 "2019-07-17T14:45:41Z")

</div>

Interesting perspective. What i actually wanted to ask is whether Elm could get rid of the virtual dom because it seems that strategy works very well for svelte. I was curious if at all no virtual could potentially bring any advantage in terms of simplicity and performance. Thanks!

---

<div class="post-metadata">

**Author:** ![evancz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/evancz/32/16_2.png) [@evancz](https://discourse.elm-lang.org/u/evancz)\
**Post date:** [July 18, 2019, 4:53pm UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/6 "2019-07-18T16:53:32Z")

</div>

My understanding is that there is not a major difference in perf based on:

> <https://twitter.com/sveltejs/status/1138094066867089408>
>
> Svelte @sveltejs

There are a lot of ways to be faster than the big name frameworks, but I don’t think using the general “virtual DOM” approach is the crucial factor.

---

<div class="post-metadata">

**Author:** ![edkv](https://avatars.discourse-cdn.com/v4/letter/e/439d5e/32.png) [@edkv](https://discourse.elm-lang.org/u/edkv)\
**Post date:** [July 18, 2019, 6:12pm UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/7 "2019-07-18T18:12:17Z")

</div>

In a project I’m working on I tried the following approach to do animations: store an `animationClock : Float` value in the top-level module and pass it down to the views that need it. This allows to not add an `onAnimationFrame` subscription each time I need an animation, but to use it only once at the top level.

Unfortunately, if I need animations everywhere and pass `animationClock` to most of the parts of the app, this approach basically makes `Html.Lazy` useless (because the value changes every frame), and the entire view tree (or most of it) must be recalculated on every frame.

It is still fast – I can’t really notice any performance issues visually. But since the view is recalculated on every frame, I can see high CPU usage all the time. To optimize this, I need to find a way to disable the subscription when no animations are running. It’s not that simple, for example some of the views that use animations are just stateless functions like `spinner : Animation.Clock -> Element msg` that show a loading spinner that just spins forever. So to disable the subscription I need to somehow know if there are any spinners rendered at the moment (and other views that require an animation).

If we used a similar technique like Svelte use (if I understand it correctly) we could evaluate the application’s `view` function only once during the compilation and detect which parts of it are static or dynamic, and changes to which parts of the `Model` affect which parts of the `view`. In this world there would be no need to do any optimizations in my example above, moreover I think `Html.Lazy` would not be needed anymore. Of course it’s not an easy task because it’s not possible to implement this on `elm/virtual-dom` level and it requires changes to the compiler, but would be cool 🙂

---

<div class="post-metadata">

**Author:** ![dmy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dmy/32/702_2.png) [@dmy](https://discourse.elm-lang.org/u/dmy)\
**Post date:** [July 26, 2019, 8:22am UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/8 "2019-07-26T08:22:11Z")

</div>

Does anyone know if the kind of solution used by Svelte would also have the runtime errors issues that virtual DOM and DOM browser extensions sometimes cause?

---

<div class="post-metadata">

**Author:** ![Herteby](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/herteby/32/1329_2.png) [@Herteby](https://discourse.elm-lang.org/u/Herteby)\
**Post date:** [July 26, 2019, 8:59am UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/9 "2019-07-26T08:59:25Z")

</div>

Svelte is based on quite restricted templates bound to specific fields on an object, and the updates only work if you use it in a certain way. If you for example use a function in a template, it doesn’t get updated when the state changes: [https://svelte.dev/repl/b272ae7c3dee478090a4c89254e4afbd?version=3.6.7](https://svelte.dev/repl/b272ae7c3dee478090a4c89254e4afbd?version=3.6.7)

In Elm’s view functions on the other hand you can use anything in the language, and they’re guaranteed to update correctly. So it seems like a totally different beast, and way harder, to make Elm work like Svelte (at least without totally changing how you write programs).

---

<div class="post-metadata">

**Author:** ![dmy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dmy/32/702_2.png) [@dmy](https://discourse.elm-lang.org/u/dmy)\
**Post date:** [July 26, 2019, 9:03am UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/10 "2019-07-26T09:03:57Z")

</div>

I see. Thank you. I didn’t take the time to understand how Svelte works.

---

<div class="post-metadata">

**Author:** ![MarkHamburg](https://avatars.discourse-cdn.com/v4/letter/m/cdc98d/32.png) [@MarkHamburg](https://discourse.elm-lang.org/u/MarkHamburg)\
**Post date:** [July 30, 2019, 3:01pm UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/11 "2019-07-30T15:01:05Z")

</div>

A virtual DOM based program is necessarily slower (more CPU intensive) than a perfect program that touched the DOM directly because the two programs will perform exactly the same changes to the DOM and the virtual DOM based program will also render and diff the DOM. Assuming, of course, that the “perfect” direct DOM program doesn’t burn lots of CPU time on some other form of change tracking…

Where the virtual DOM gained traction is that assuming you don’t have a perfect direct DOM program, then it either updates the DOM less frequently than it should — bugs!!! — or it updates it more frequently than it should — potentially a big performance hit since DOM mutations aren’t or at least historically haven’t been cheap. Not wanting buggy updates, direct DOM approaches biased toward updating more often than necessary and burned performance. Virtual DOM implementations paid for themselves by reducing the cost spent on updating the DOM at the expense of rendering and diffing.

Direct DOM programs claw their way back either indirectly when browsers make DOM manipulations faster thereby reducing the costs of over updating. Or they look for cheaper ways to track the updates that need to be performed, potentially trading off some precision while doing so. Svelte falls into the latter category. By constraining the problem more tightly, Svelte builds a model of what changes to propagate to the DOM that is cheap to maintain and use.

Elm gets a big performance benefit out of the fact that view functions have no side effects and hence the meaning of a program won’t change if they are never called or more practically if they are called only per animation frame. That said, Svelte could probably do its dirtiness tracking and only apply changes on animation frames as well. I don’t know whether they do this.

Elm’s lazy HTML is a way to cutoff branches of the view tree from the render and diff process when their arguments don’t change. Where this works, it can be quite beneficial. On the other hand, if used in places where arguments change frequently or are calculated — e.g., building a record — it adds overhead while achieving little or no reuse. It also has trouble with more complex data flow patterns. For example, if one has a large, expensive to compute layout that depends on the items in the layout (rarely changing) and the view width (rarely changing) and we want to only render the portion that is visible (dependent on the rapidly changing scroll position), there is no good point within the view logic to insert a lazy node to cache the layout computation that won’t have this cache destroyed on scroll events. Instead, one ends up making the layout a part of the model and managing its update there even though it adds no extra information to the model that wasn’t already present and hence undermines efforts to make impossible states impossible.

This is akin to the recent discussion of GC. Precise storage management is hard. Precise DOM updates are hard. We choose to trade some imprecision, some performance, or some capabilities to get a programming model that works “better” in practice. Elm makes one set of choices. Svelte makes another. React makes yet another.

Mark

---

<div class="post-metadata">

**Author:** ![edkv](https://avatars.discourse-cdn.com/v4/letter/e/439d5e/32.png) [@edkv](https://discourse.elm-lang.org/u/edkv)\
**Post date:** [July 31, 2019, 9:02am UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/12 "2019-07-31T09:02:43Z")

</div>

> [@Herteby](#):
>
> In Elm’s view functions on the other hand you can use anything in the language, and they’re guaranteed to update correctly. So it seems like a totally different beast, and way harder, to make Elm work like Svelte (at least without totally changing how you write programs).

I think it should be possible to analyze the AST during compile time to determine dynamic parts of view and how they should be updated in case of updates to the model. I’m not saying that’s easy to do, but no need to change the way you write programs.

---

<div class="post-metadata">

**Author:** ![rupert](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rupert/32/1775_2.png) [@rupert](https://discourse.elm-lang.org/u/rupert)\
**Post date:** [July 31, 2019, 9:24am UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/13 "2019-07-31T09:24:33Z")

</div>

> [@edkv](#):
>
> I think it should be possible to analyze the AST during compile time to determine dynamic parts of view and how they should be updated in case of updates to the model.

There was something about that in the news not so long ago, was it in regard to SwiftUI? I’ve never been an Apple developer so did not really register the details, perhaps someone who knows can provide a link?

I think the idea was that there is an side-effect free language for describing UIs, and the compiler is automatically able to infer which parts are static and which dynamic, and use that to optimise the UI construction so that only the dynamic parts ever need to be re-computed.

I also have this book, which gets into the theory of how this kind of thing can be added to functional languages: [Two Level Functional Languages](https://www.cambridge.org/gb/academic/subjects/computer-science/programming-languages-and-applied-logic/two-level-functional-languages?format=PB)

Elm Virtual DOM already performs very well - so from the point of view of effort vs reward in implementing this kind of advanced optimisation you have to wonder if it will ever be worth investing the effort.

---

<div class="post-metadata">

**Author:** ![edkv](https://avatars.discourse-cdn.com/v4/letter/e/439d5e/32.png) [@edkv](https://discourse.elm-lang.org/u/edkv)\
**Post date:** [July 31, 2019, 10:23am UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/14 "2019-07-31T10:23:18Z")

</div>

> [@rupert](#):
>
> Elm Virtual DOM already performs very well - so from the point of view of effort vs reward in implementing this kind of advanced optimisation you have to wonder if it will ever be worth investing the effort.

Please take a look at my post above about animations. The approach I tried wastes too much CPU power by recomputing/diffing the entire view on every animation frame and makes `Html.Lazy` useless. I can’t think of another way to optimize it rather than managing state and subscription for every spinner or other animatable view (my idea about disabling the global subscription when no animations are running is not perfect because if I do it the whole view would still be recomputed on every frame during animations). I will probably switch to CSS animations.

---

<div class="post-metadata">

**Author:** ![rupert](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rupert/32/1775_2.png) [@rupert](https://discourse.elm-lang.org/u/rupert)\
**Post date:** [July 31, 2019, 11:02am UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/15 "2019-07-31T11:02:29Z")

</div>

> [@edkv](#):
>
> I can’t think of another way to optimize it rather than managing state and subscription for every spinner or other animatable view.

I took this approach with the one application I wrote that had a significant amount of pure Elm animations in it. It seemed to work out ok, but I arrived at this option just by luck as it was the first way I tried it. It is not the easiest as there is a fair amount of overhead in hooking up all those subscriptions.

I also took that approach because I did not know CSS animations - now that I have some experience with them, I would generally prefer them where possible, and keep the amount of pure Elm animation to a minimum.

But yes, I think your use case is a valid one for this kind of optimisation. It would be pretty sweet if Elm could pull that off - theoretically I think it is entirely possible.

==

It is also worth mentioning as others have noted that pure Elm animations may not perform so well on mobile devices with their weaker CPUs. CSS animations are more likely to have been optimised by the browser implementation and more likely to run smoothly.

---

<div class="post-metadata">

**Author:** ![edkv](https://avatars.discourse-cdn.com/v4/letter/e/439d5e/32.png) [@edkv](https://discourse.elm-lang.org/u/edkv)\
**Post date:** [August 1, 2019, 11:35am UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/16 "2019-08-01T11:35:04Z")

</div>

> [@rupert](#):
>
> It is also worth mentioning as others have noted that pure Elm animations may not perform so well on mobile devices with their weaker CPUs. CSS animations are more likely to have been optimised by the browser implementation and more likely to run smoothly.

well, that’s debatable 🙂 I’m not an expert in this field, but I read in the past that JS animations can be as fast or even faster than CSS. Also, CSS transitions/animations have another issue – they store state outside of elm’s model and it can be assigned to a wrong node after diffing. So it’s often necessary to use keyed nodes, and you need to make sure that the keys are unique among “instances” of the same view (like a row of buttons that have mouse over transitions, and buttons can change dynamically). I’d prefer to do animations in elm instead.

---

<div class="post-metadata">

**Author:** ![dmy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dmy/32/702_2.png) [@dmy](https://discourse.elm-lang.org/u/dmy)\
**Post date:** [August 1, 2019, 11:36am UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/17 "2019-08-01T11:36:43Z")

</div>

> [@edkv](#):
>
> Also, CSS transitions/animations have another issue – they store state outside of elm’s model and it can be assigned to a wrong node after diffing.

Interesting, never thought about that or noticed it. Thank you.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [August 11, 2019, 11:36am UTC](https://discourse.elm-lang.org/t/could-updating-the-dom-directly-instead-of-the-virtual-dom-get-any-advantage-for-elm-the-way-it-does-for-svelte/3995/18 "2019-08-11T11:36:45Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
