6 ms·
The compiler treats everything as static by default. When the compiler detects something dynamic (such as a {{mustache}} template), it will mark the current nod
by kbr 9y ago
The compiler treats everything as static by default. When the compiler detects something dynamic (such as a {{mustache}} template), it will mark the current node as dynamic, and the parent node as well.
These propagate up the tree so Moon eventually has a render function that is extremely optimized and can skip everything static, and the diff will only hit the nodes that can change.
Moon also has a stricter syntax for virtual DOM, allowing for less checks to be made at runtime compared to alternatives like HyperScript. This is made possible because Moon's compiler itself is in charge of creating the render functions, allowing it to give certain hints to the virtual DOM diffing engine.
There is really no way to avoid GC when you have a virtual DOM. The virtual DOM trees are pretty light and have memory usage similar to that of React and Inferno.
- oever 9y ago> There is really no way to avoid GC when you have a virtual DOM. If you keep the virtual DOM in a typed array, there is not need for relying on the JavaScript garbage collection. Here's an example: https://github.com/vandenoever/baredom/blob/master/src/baredom/impl/Dom.js https://github.com/vandenoever/baredom/blob/master/src/bared...
- pspeter3 9y agoThanks, I'll have to check this out!
- kbr 9y agoThis is really cool! I'll definitely look into this and apply some of it to Moon.
- oever 9y agoBareDOM is a proof of concept, the code is not very clean, but I'm sure you can get the ideas. Since Moon has a specific way of using the DOM, you might be able to cut down on the number of array positions per node (currently 8).
- pspeter3 9y agoIs there any documentation on why to use a typed array
- yorwba 9y agoTyped arrays are essentially tightly packed chunks of memory that the GC won't walk. If you know what you're doing, you can use them to both save memory (shaving off the per-object overhead of JS objects) and reduce the time spent on GC collections (but you have to do your own memory management on the typed array). That the typed array contains only objects of a single data type probably also helps the JIT to optimize.
- leeoniya 9y agowhat's the cost of resetting & reusing pre-allocated memory vs letting the GC discard stuff. if the cost of resetting is greater than the cost of collecting & re-allocating, then you're in the same place. at least in my experiments of trying to reuse already-allocated virtual nodes and resetting their properties was slower than simply unreferencing them for the GC and re-allocating new ones. have you tested the tradeoffs of your approach in modern browsers? (i see the repo is somewhat dated).
- oever 9y agoI just reran the test page in the repo and browsers have certainly improved. The gains have shrunk to the point (2x speedup at best) that the use of an unsafe API would not be recommended for general use. The test can also run a 'Simple' virtual dom which is a naive implementation with Javascript Objects. That one is currently faster than the typed arrays in Firefox, but in Chromium, the typed arrays are still much faster. As a vdom hidden behind an API like in the case of Moon or Vue, typed arrays could still make sense.
- leeoniya 9y ago> The gains have shrunk to the point (2x speedup at best) call me a skeptic, but i suspect that whatever impl you're comparing against is not terribly good. this bench [1] allocates (and discards) ~3,000 virtual nodes per redraw, and each redraw is ~1.3ms, pegged @ 60fps. the GC time is ~2% [2], so even if all GC went away, a 2x speedup is plain impossible. unless you're suggesting that the majority of the time spent in "Scripting" is heap allocations, which i'll concede may be a good amount - do you know if there's a way to measure cumulative time spent growing the heap? [1] http://leeoniya.github.io/domvm/demos/bench/dbmonster/ http://leeoniya.github.io/domvm/demos/bench/dbmonster/ [2] http://imgur.com/a/TwwRf http://imgur.com/a/TwwRf
- oever 9y ago> whatever impl you're comparing against is not terribly good. Indeed it is not. The reference is a naive Object based DOM. The benchmark is also not using complete rendering and diffing: it uses versioning on the nodes. It replaces the updated dom nodes at a configurable rendering frequency. So it's very different and probably slower than current frameworks. The remark that triggered the mention of baredom was the supposed unavoidability of the GC. Baredom does not use it and WebAssembly might make non-GC VDoms popular. Still, JS engines GC has gotten very good.
- pspeter3 9y agoThanks, that makes a lot of sense. It sounds like the compiler is providing most of the benefit. Agreed about GC. It's a significant portion of time in Asana for large task lists.
- IgorPartola 9y agoIs there a fundamental reason that Vue couldn't take the same approach?
- kbr 9y agoYes, and that is because Vue uses hyperscript. This allows you to use JSX, but at the same time makes a render function slower. Since Moon's virtual DOM syntax is stricter, it allows for the compiler to make lots of optimizations.
- spankalee 9y agoThis is really great to see the emphasis on static vs dynamic parts in templates. Polymer, Glimmer, and some other template systems make the distinction between static and dynamic content, but React and most other vdom libraries don't. I was looking for options for HTML templating in JS found that JS template literals very naturally separate static and dynamic sections between the literals and expressions. I've been testing a library based on them [1], and for real-world templates with large static sections, it's indeed faster than traditional vdom. [1]: https://github.com/PolymerLabs/lit-html https://github.com/PolymerLabs/lit-html
- localvoid 9y ago> This is really great to see the emphasis on static vs dynamic parts in templates. Polymer, Glimmer, and some other template systems make the distinction between static and dynamic content, but React and most other vdom libraries don't. https://github.com/facebook/react/issues/3226 https://github.com/facebook/react/issues/3226 All other "static" optimizations doesn't make any noticeable difference in performance in highly optimized vdom libraries. In fact, they are usually decrease overall performance because of increased implementation complexity.