Million.js with Aiden Bai PROTOOLS === [00:00:00] Hello and welcome to PodRocket, a web development podcast brought to you by LogRocket. LogRocket helps software teams improve user experience with session replay, error tracking, and product analytics. You can try it free at logrocket. com. I'm Noel. And today we have Aiden Bai here to talk to us about the virtual DOM. Aiden is building Million. js, the virtual DOM replacement for React. Welcome, Aiden. Hi, glad to be here. Awesome. Yeah, I'm excited to chat today. Let's set this one up. I feel like virtual DOM is one of those things that everyone knows about loosely. It's like one of those dark magics. People don't like to think about too much or worry about thinking about too much, maybe. But can you kind of set this up for us? What role does the virtual DOM play in general? How does that interact with React? And what are some of the potential friction points there? Yeah, when you hear virtual dom, it just basically means somebody wrote a piece of code that can change UIs. For [00:01:00] example, when you click a button, it will change the button to be red or like a count to go up. And the way it does it is if you can imagine the virtual dom is like a small child and this small child just learned how to like Draw on a whiteboard and then it wants to communicate to its adult that it wants something to be done For example, the virtual dom could be like I have a blue ball And then I want to add like a little red hat to the blue ball the virtual dom would draw the old version Which is just the blue ball and the new version which is the blue ball with the red hat and show to the adult And they'll be like, oh, okay. I know how to do this takes a red hat and puts it on the blue ball. Basically, as this relates to UI, web UIs, you're given basically two snapshots of the UI. Some sort of reconciliation engine determines the differences between those two snapshots, and then it makes the actual changes to the DOM, or the web, or the UI. Gotcha. Gotcha. Are there any common misconceptions people have about the virtual DOM? That the virtual DOM is [00:02:00] fast, and the virtual DOM is slow. That are really, really famous. One by React, which is It's perpetuated the thought that the virtual DOM is faster than the DOM. And there's also this article by Rich Harris, the creator of Svelte, who wrote virtual DOM is pure overhead, which is basically the virtual DOM is slow. And it's both and not both at the same time. The virtual DOM is not faster than the DOM. Like you can write faster code with the virtual DOM, but generally speaking, React is slower than vanilla JS. Right. But it's also like not as slow as you think. There are certain cases where it's pretty fast. Pretty efficient. And there are also certain cases that are really slow. Do devs typically find themselves wandering into these slow use cases unknowingly or is this all largely just framework stuff? It's not something that's impacting devs day to day. It depends on the UI. So let's take like Facebook, for example, like what react was made for. There's a lot of structural changes, like structural updates. And what I mean by that is when you click a button, like a feed will pop up or something like that, or like a profile page or like a [00:03:00] modal, and those are like very structural changes. It's not like. I just changed the title of a certain UI. It's I replaced the entire UI when I do something. And that's what the virtual DOM is really good at. It's basically, it goes through this process called diffing. So it checks basically each element within a component or UI, and then. It figures out the differences and then makes the necessary changes to the DOM. And so with structural changes, a lot of things need to be changed, and the virtual DOM can do that really well. But what it's not good at is, like, value based updates. Like, what if I only change a title? Or what if I only change a specific color? And as the UI gets bigger, And the more value updates you have, the referral time gets really bad. Cause you're like checking the entire UI, but only changing one thing every single time. Is there like some way that people should be thinking about this or are there recent updates that have happened that have made this like easier for devs to reason over? Why is this something we should be thinking about right now? I think if you own an M1 MacBook and you're the 99 percent of [00:04:00] devs in the first world, it probably doesn't matter for you. You probably never experienced it, but you will experience it one day. And like,~ ~~like, once that happens, you have to, there,~ there are some patterns you can use. You can memo, you can structure your components. This is why I wanted to work on NulliJS. I was like, it's pretty hard to do these. performance changes, especially at a really large scale. Once you have thousands of components, it's hard to keep track of how was the most optimal structural way to organize these things. At the end of the day, you just want something to plug in and not care about it. Gotcha. So yeah, let's set it up. What is Million. js? Why is it different? What's the overview? Yeah. A million JS is a virtual DOM replacement for React. It essentially looks for problematic components, replaces the virtual DOM that renders it, and then makes it faster on specific benchmarks. As of Chrome 120, it's around 70 percent faster. Which is pretty cool. Are there other tools like this? Is Million. js kind of the first prominent tool in this space? Or are there other things you've built on?[00:05:00] As far as I know, there is no virtual DOM replacement for React. There are like certain things you can do to optimize React application, but none of them go into the scope of Million. js. But the concepts that Million provides are pretty common within other frameworks. Solid. js is like a good example. Million. js is basically Solid. js without the state and signals. It's also Svelte, basically. Like under the hood, it's basically just Svelte. It's originally derived from this small library. That's being used by a couple of companies called BlockDOM, which introduces a very fast virtual DOM implementation. And basically what Million does, it takes that virtual DOM implementation and then applies it to React. Explain a little bit more about BlockDOM. What is it? What is kind of the abstraction that it makes? How does it differ? Just like from a traditional virtual DOM. Before we do that, we should take a step backwards into virtual DOM. I mentioned the concept of diffing, where you check each element. But the way it does that is it organizes the UI into a tree. And so you can [00:06:00] see like a container could be like the root element, the root node, or like image could be like a sub node, and children node, and so on and so forth. And for CS students, it's like the correct terminology is n tree. What it does, it has to traverse, every time there's an update, it has to traverse this tree and check for updates for each one. So the issue is like the time complexity is not the best, right? But what if you could discriminate between nodes? For example, not every node is the same node. For example, like one node could be like a node that constantly updates and one node could be like an image node that never updates. So what you can do here is. Instead of traversing over the static nodes every single time, you just don't traverse over them, and you go to the ones that change a lot, so your traversal is significantly less for each time. And so, you skip the static nodes, you traverse the dynamic nodes, and You have much less computation per update. Just to help contextualize this, when is this diffing usually happening? Every single time there is a, a re render, like your state changes, or like props change or [00:07:00] Yeah. A healthy react app, right? When the state of props change. Yeah, exactly. Exactly. Cool. Nice. So then what does the block DOM do? Is, is the block DOM, I guess what you were saying before, right? There is some kind of mechanism that's ensuring that only the modified nodes are diffed. Exactly, ~yeah~~. ~~Um~~,~ instead of diffing the actual modified nodes, it diffs the state of it. ~For example~~,~ yeah, much more efficient that way. I mean, this seems very like intuitive when we talk about it in abstract terms like this, but how does that actually like manifest? What does that mean? If you're using,~ if you're using ~this tool, like something with a block instead of a traditional virtual DOM. Yeah, you have to make some assumptions first. For example, like, you're assuming that this UI is very much a value based change. Changing UI. If you think about it, you don't want to optimize things that are going to structurally change because it's going to get blown away anyway. So one thing that blockdom does very different is you have to write a compiler. You had to do like a head up time step with react. It's really nice. You just run the virtual Dom and ~you don't~~,~ you can indiscriminately. Shove nodes into the virtual DOM and say, okay, figure out what's the difference. [00:08:00] But with the block DOM, you have to look at the component before and then be able to run it. Block DOM has this really weird esoteric string formatting thing that they use. And then Million uses a compiler to figure out the actual dynamic node. In this case, it's pretty easy because I can just see like the expressions, like if you have like an expression inside your code. Then yeah, that's dynamic. If it's like a div, then it's not dynamic. So when someone's. Switching to Million. js or thinking of, or Million. js is used instead of the virtual DOM. Is there some subset of apps or maybe certain patterns that could lead to every DOM still being effectively like a DOM that would need to be diffed? Or is it pretty hard to do that? Do you find that there are almost always lots of static nodes in these React apps? We have a mode called automatic mode, which figures that out for you, which is really nice, like there are certain trade offs, but you don't really have to worry about them conceptually. You can think about it. For example, structural nodes. You don't want to optimize value based updates, for example, components with lots of static nodes [00:09:00] and like very few, very nested dynamic elements are great optimizations. Lots of dynamic nodes, also good optimization. With static nodes in front or something, but yeah, you don't have to think about that anymore, which is What does that integration process look like? Is it a significant undertaking to switch to Million. js if you're just one's just using the out of the box react virtual DOM? If you're using a major framework or a major bundler, it's just running one command now. It's just like npx space million at latest, or if you use like some other yarn. So yeah, it's a five second setup right now. Is there any reason devs should shy away? Or would you encourage everyone do this to your app? Try it. See how it feels. If you're using it in a production environment, you should probably evaluate. Like the only reason I can think is there is an added compile time. So as you're building the application, you'll notice somewhat of a delay. Like on my computer, I have M1. On a thousand components is about roughly 200 and 500 milliseconds delay.[00:10:00] You could have security concerns. Hopefully we don't have any security issues, but like probably you should think of that we do have some limitations such as we do insert an extra element for each block, which has been recently fixed in v3, but not really. Which is why I encourage a lot of companies to be like, you just try it out. Like there, there is really no downside here. I feel like just anecdotally, I've heard pretty good things from most devs that go in and try it like, yeah, this is great. It was an easy to plug in and win again, even just seeing benchmarks and stuff. Do you guys have any stats you're keeping track of or benchmarks or anything that you like to point developers towards? Yeah. Million is top five fastest frameworks in, uh, the JS framework benchmark. If you look it up, like it basically lists 200 major, not major frameworks, the 200 frameworks, including major frameworks. And yeah, if you just look, it's there top four, top five. It's really fast, Nice. I know, again, like I was saying, there's been a lot of traction. Do you have any idea of adoption or number of projects [00:11:00] that are using this in production? Any grasp? but it's like an estimated 10, 000 so far. We have around five, 500, 000 NPM installs per week or per month. Around 13, 000 stars as of current. I think it's around 10, 000. don't have a super strong grasp here on the history of the project. I feel like I started seeing it maybe three to four months ago, five months ago, but I'm not sure if it was just gaining more traction. How long has this been a project for you? It's been two years, like, I started this because, yeah, it's been really cool. The first year I started off with, it was like, really bad. Like, I tried making a virtual DOM, which I learned a lot through that, but it was actually slower than React. I don't know, I just kept going. Ryan Carniato was one of like, huge inspirations, creator of SoloJS. Marvin, who's on the Preact. js team has been a huge inspiration as well. Just so many people in web dev are really helpful. They provide resources and I probably would have taken longer if it wasn't for. Yeah. We've had Ryan on Ryan's awesome. He's like such a enthusiastic human. He's just like so [00:12:00] excited to be working on stuff. It's so good. And yeah, like Richard, you've mentioned before, always a pleasure to talk to you. It seems so full of life and like wanting to make everyone's lives better. It's great. So I'm curious what you said options been pretty substantial. Has there been any discussion or like talk on making something like. million the default or making this something easier for devs to just wind up in without having to seek it out explicitly. There are some thoughts here. I think React is providing its own solution to the problem. So if you've heard of React for Git, it's like a compiler for React. And so it does solve part of the problem where it's like. You can divide React's updating phase into rendering and then reconciliation. Rendering is the part where it runs the component and returns the JSX. Reconciliation is, it takes this returned JSX and figures out differences and makes updates to the DOM. The problem they solved is, sort of solved, is rendering the JSX. Running the component and returning the JSX. Not doing that as frequently or like unnecessarily. The problem of [00:13:00] reconciliation is still pretty unsolved. Maybe for good reason because not that many web issues are like because of that, but that's what React is working on. There's also some issues you can't really directly integrate yet. The implementations are so different that you have to kind of rewrite all of React around this idea before it actually becomes a default. So for devs listening, would you implore them to check it out regardless? And like always make this something they consider just like when looking at performance optimizations or even like starting a new project, do you think ~it's~~,~ it's pretty well suited? If you're running any application, there is no downside other than maybe compile time, if your thing is really large. If you're using React for Git right now, you can use it alongside Million. So that's the nice thing. There's not really a downside. I like, I can't think of any major downsides unless you have specific like architectural constraints or like some security issue. Yeah. Well, again, we can just leave listeners with that then. Is there, is there anything else you'd implore people listening to check out? Is there anything you need help with? What would you ask of listeners? Yeah, we're working on our [00:14:00] documentation. Frankly, we only have three pages to our documentation because we, our install process is just like one line of code. But if you're interested in documentation, we're looking for people to help contribute to that. Translation is always like a helpful thing too. Spreading the word. If you're like, Oh, I'm using Million. This is really cool. This is how much speed boosts. Post a screenshot to Twitter. We gotta get the million gain going. Yeah. The million gang. Nice. Nice. Cool. Thank you so much for coming online and chatting with me. It's been a pleasure. ​