4 ms·
https://i.imgur.com/MG3eGTM.png https://i.imgur.com/MG3eGTM.png Inferno here is also slightly patched[1], instead of using stateless components, it is using st
by localvoid 8y ago
https://i.imgur.com/MG3eGTM.png https://i.imgur.com/MG3eGTM.png
Inferno here is also slightly patched[1], instead of using stateless components, it is using stateful components to demonstrate how fast it can go down when you start using high-level abstractions in a library that focuses only on low-level primitives.
And if you really want to understand the fundamental flaw in libraries with fine-grained direct data bindings, try to reimplement this[2] 70 lines of React code with such library.
1. https://github.com/localvoid/js-framework-benchmark/commit/225eff5c53eb800599eb979d1f402f30d308a916 https://github.com/localvoid/js-framework-benchmark/commit/2...
2. https://github.com/localvoid/uibench-react/blob/master/js/fc.jsx https://github.com/localvoid/uibench-react/blob/master/js/fc...
- naasking 8y agoAh, I forgot to check Ivi. Still, Surplus, Ivi and vanilla JS are the top 3. Clearly the virtual DOM is difficult to optimize. Surplus is itself also largely unoptimized because it largely didn't need to be at the time. I had a discussion with the author on incremental reduce optimizations in the S.js issues section. Anyway, I have nothing else to say on the matter. Clearly anything with only 10% overhead over vanilla JS is definitely fast enough, and Inferno is there now if you want something React-like. As an aside, do you have any experience with Ivi? I'm looking to learn something else and wondering if I should dig into Web Components or something like Ivi. Web component performance was terrible last I checked.
- localvoid 8y ago> Clearly anything with only 10% overhead over vanilla JS is definitely fast enough And now is the main question :) If virtual dom is competitive in benchmark that is super biased towards direct data bindings libraries, what is the point of using direct data binding solutions when they won't be able to handle even basic use cases that involve client-server communications when server sends data snapshot. There won't be any information about data changes, and you'll end up with reimplementing tree diffing algo, so that you can apply it to the data.
- naasking 8y ago> what is the point of using direct data binding solutions when they won't be able to handle even basic use cases that involve client-server communications when server sends data snapshot. I'm not sure what you mean. Surplus is built on S.js, in which all data is lifted into reactive expressions. S.js already handles that for you but at the data model level, where it arguably should be, not at the UI model level.
- localvoid 8y ago> S.js already handles that for you but at the data model level It only works as long as it is able to track changes, many client-server applications doesn't send you list of changes that you should apply to your data, they just send you data snapshots. With virtual dom library I'll just update my data and rerender everything that depends on this data, with direct data bindings good luck figuring out solution to such simple problem.
- naasking 8y ago> With virtual dom library I'll just update my data and rerender everything that depends on this data So you have to visit every data node, and then also visit every changed UI node. Where if you have deltas, you only visit changed data nodes and then changed UI nodes. Re: data snapshots, it's easy to design your own service to use a delta protocol. But even when you can't, you can separate the code used to construct your reactive objects from the code that initializes them. This is just basic function abstraction, and it doesn't really add any work. From the example on S.js site: const // a = S.data(1), // a() | 1 3 3 5 b = S.data(2), // b() | 2 2 4 6 c = S(() => a() + b()), // c() | 3 5 7 11 d = S(() => c() * a()); // t0 // d() | 3 15 21 55 a(3); // t1 // +------------------------> b(4); // t2 // t0 t1 t2 t3 S.freeze(() => { // a(5); // b(6); // }); // t3 // Now becomes (quick and dirty to convey the idea): const a = S.data(1), b = S.data(2), c = S(() => a() + b()), d = S(() => c() * a()); update(3, 4); S.freeze(() => update(5,6)); function update(aval, bval) { a(aval); b(bval); } S.js will detect whether the value you're providing is actually different, and will only propagate what has changed. Roughly the same number of lines of code, just more reusable.