wintergatan-community / virtual-mmx

A WebApp to program songs on a virtual Marble Machine X
https://wintergatan-community.github.io/virtual-mmx/
MIT License
36 stars 15 forks source link

Switching from React to Solid JS? #37

Open Zakgriffin opened 4 years ago

Zakgriffin commented 4 years ago

This is more of an open discussion than a suggestion since I realize the magnitude of such a change. I'll try to keep this short, we'll see how it goes.

React operates fundamentally on a Virtual DOM, a mechanism that has become extremely popular in most modern JS frameworks (i.e. React, Angular, Vue) which is fantastic for declarative components with JSX. However, the primary issue is that our project has a lot of timeline editing, and making small changes to a data structure, like changing the timing of a drop event, causes every other event in that timeline, or at least a chunk of events, to check if they need to rerender due to the top down concept behind a virtual dom.

Also, state management in React out of the box is either cumbersome, or inefficient. The main way to store state is either using React hooks' useState, or class components' this.setState. These both uses diff reconciliation on every state change, which again, for timeline editing is very inefficient. Passing state through layers of components is also cumbersome, with an alternative being React Context, which makes sharing state for a tree of components much easier and cleaner, but is ridiculously inefficient. Some of this inefficiency can be avoided with 3rd party state management like MobX, but this can only help to an extent (currently this.setState and useState are never used for the VMMX, as we've been using MobX).

Another thing to mention is that React offers two ways of making components: classes, or functional hooks, and both approaches have their problems. Class components, what we currently use, have a jarring issue where instance variables call twice as many times as a component is mounted, and functional components rerun the whole function each render, which requires very cheaty and magic feeling JS tricks under the hood which are the foundation of hooks.

I propose we switch to the Solid JS framework since it focuses heavily on true reactive programming, meaning the virtual DOM mechanism is replaced with a more fine grain system that intelligently updates components only when their dependent state changes. Importantly, components are structured near identically to React hooks (which the VMMX used for a while, converting components is not difficult). The difference is that in Solid, component functions only run once on mount, return plain old DOM elements, and all state changes from that point forward are fine grain. There's also no need for third party state management like MobX or Redux and Solid implements a Context system, again very similar to React's but more efficient for small changes.

Again, I understand that switching the framework of the project is a pretty huge change, but I feel we're not exactly stuck with React yet. Switching to Solid would cut bundle size, increase performance, and generally I feel it's easier to understand cutting out a lot of the "magic" that keeps some vanilla JS developers from feeling they can't approach a framework. I'm open to hearing what everyone thinks of this idea, sorry to make this write up so long, I wanted to fully explain my thought process.

Solid JS - https://github.com/ryansolid/solid/tree/e24c781545720df07985ddf3f8fd121d75f2df46 The talk that made me start looking into this a few months ago. It gives a good explanation for where the inefficiencies of the virtual DOM come from, and Rich Harris's solution, Svelte which uses a very similar approach to Solid - https://www.youtube.com/watch?v=AdNJ3fydeao

FelixWohlfrom commented 4 years ago

To summarize the discussions in discord starting here https://discordapp.com/channels/649165975647682560/712733531687878676/743581936420782160:

Imo we should really go for a framework that is quite easy to use and has a high performance in regards of maintaining hundreds of elements. E.g. in a normal performance, we will have a lot of ticks on the programming wheel, plus the performance specific events.

Since react seems to be quite slow in case you manipulate a dom having hundreds of elements, but solidjs doesn't have that issue, we can go for that.

But if we switch to a different framework, we should also check how well it is maintained (solid seems to be quite alive), if there is some documentation available and how easy it is to start as a newbe (since there seem to be several people who would like to join the project, but are more used to vanilla js).

Personally, solid seems to be quite easy to use and has at least some examples. And since it seems to be faster than react, I would just suggest to switch to solid for now.