adamhaile / surplus

High performance JSX web views for S.js applications
639 stars 26 forks source link

Improve quantification of advantages #57

Open brodycj opened 6 years ago

brodycj commented 6 years ago

I really like the advantages this framework has to offer in terms of eliminating the performance/complexity/interop costs of a virtual DOM but think this needs to be made much more clear. From current results [1] of krausest / js-framework-benchmark [2] I see very limited performance advantages over Inferno and Nerv, and they seem to beat Surplus as well as each other in certain cases. The current results in [1,2] make it very difficult to justify using this framework over the industry-proven React-style front-end APIs offered by the performant Inferno and Nerv frameworks. This case becomes especially challenging if we would consider the existence of React Native, now with interop with a number of popular libraries and frameworks such as ReactXP, Vue/RN, Angular/RN, etc.

It would be great if we could find a way to better quantify the advantages of using this framework over the existing VDOM-based frameworks, at least in a certain class of applications. I did really enjoy updating the CodePen sample, watching whether or not the demo would keep working as I made the proposed cleanup changes in #56.

[1] https://rawgit.com/krausest/js-framework-benchmark/master/webdriver-ts-results/table.html [2] https://github.com/krausest/js-framework-benchmark

P.S. ds300 / ddom seems to offer some similar functionality (get rid of VDOM), using the React JSX compiler.

adamhaile commented 6 years ago

I have no interest in "winning" any framework wars, or in disparaging other libraries. React is a very useful library, one I've used and still use in many projects. Inferno's perf gains with v4 are impressive -- congrats to its authors. I don't know Nerv well, but wish them the best.

At the same time, I don't think we're at an end to the changes in the JS ecosystem. There will be something after React, which also probably means after the React work-alikes. And as long as that's the case, we need people trying out alternatives and seeing what works, what doesn't.

I think React has two really good ideas:

But React has two shortcomings:

Surplus is an experimental solution to those two issues.

If I were to rank reasons to try Surplus, I'd say:

  1. you find S's model of state management compelling (automatic dependencies, a unified clock). More specifically, if you're not interested in that, there may not be enough left in Surplus to be worthwhile.
  2. you want to try a real DOM library
  3. it's JSX, so you have both good tooling and an exit plan if it doesn't work out
  4. performance.

There are two ways to be fast: do stuff faster, or do less stuff. Surplus is largely fast from the latter. There's not a lot of abstraction between the JSX you write and the DOM operations it generates. It almost treats JSX as a macro language for the DOM. In my mind, that simplicity is really the more important quality than performance.

ryansolid commented 6 years ago

I'm just going to chime in even though I have no connection to the development of this package, and what follows is opinionated but maybe as an outsider I can provide a bit different perspective.

The fact that this is even a conversation puts some merit in the potential of this sort of approach. In many ways Surplus seems to be a modern take on techniques that pre-existed the rise of React and it's component model. There are a few different ways to handle change detection and rendering and while fine grain change detection hasn't had a champion for a while(I don't count MobX as most of it's performance benefits get lost in it still feeds into VDOM) this library shows it's potential in modern JS.

Personally while the performance is an area of interest for me it is also the the API that immediately caught my attention. Not so much what's there but what's not there:

  1. Lifecycle Functions: I have never been a fan of these all the way back to being introduced to onLoad in ASP.NET. They lead to large switch statements grouping together code that has nothing to really do with each other. The more there are the larger number of things you need to know. There is stuff like shouldComponentUpdate which people don't pay attention to initially which come to bite them later (especially where performance matters like in React Native). Instead of describing the behavior once you are coming up with conditions to optimize rendering. Specific data and concerns get split over several lifecycle functions instead of being managed in one place. At a certain point while it's all just data manipulation it feels very imperative, where the short succinct pure computations found in Surplus read more declaratively. One feels like a set conditionals and instructions and the other feels like a grocery list.

  2. Prescribed Class Inheritance: Sure you can use classes with Surplus. but since conceptually the render function runs once it can also just be a function with state wrapped as a closure. Stateless Functional components have been all the rage with React recently. But Surplus lets you use that type of syntax for every component Stateful or not for that reason (and that there are no need for life cycle functions. "Components" as functions are truly homogenous and there is nothing specific you need to inherit. This means HOC's and other fun stuff can still apply here, as you can always compose your behavior by mixing in props. I recently was playing around with wrapping Web Components as a HOC for cross framework consumption and Surplus' lack of prescribed structure worked so nicely and naturally.

  3. A Layer between your code and the DOM: This is more arguable since the abstraction provided by VDOM's make it easier to make something like React Native work. There is always things like NativeScript. Ever have some fun debugging virtual DOM nodes. I know great tooling etc, but for someone already familiar with the DOM being able to see the straight statements and just drop a breakpoint right in there is wonderful. I mean you get to shed all this extra stuff and you don't lose performance. It means also it plays much nicer with others. You don't have to buy in on a framework. The argument that React isn't buying in on a framework and it's just a render library only goes as far as the fact that there are so many similar approaches.

That all being said there are still tradeoffs. CycleJS is another framework which is very different than others that suffers similarly. The difference there is Surplus isn't so opinionated in it's functional approach, and to me the fact at any given point in time you can still know the value of moving parts makes it a lot simpler. For me the standouts are:

  1. S: Don't get me wrong I like S. It's just something people would have to learn. But this isn't RxJS. To get started you need to know S(), S.data(), and arguably S.freeze(). That gets you to the level where you know enough to be dangerous. I do appreciate how React's state feels simple like a basic object. I don't think this is out of reach of approaches like Surplus if they wanted to use ES2015 Proxies. S being fine grained has some benefits for interoptability as it doesn't need extra logic to control change detection. It isn't hard to see it interact with TC39 Observable spec, and in so integrating 3rd party stores is either trivial or require a generic data diffing mechanism that wouldn't need to be implementation specific.

  2. JSX Interopt Again this isn't really a bad thing. It's just understanding Surplus uses JSX like the way Angular uses string templates. It isn't for abstraction it's to produce concrete and specific instructions. So it doesn't quite have the same can I have Surplus JSX generate blank virtual dom syntax. But given the way it works I'm not sure that makes any sense to do anyway. JSX does a lot of really nice stuff here as a template language, letting natural JS be the DSL, allowing Functions to be represented as Components, and simplifying complexity around parsing attribute bindings.

I feel Surplus place is a bit similar to something like hyperHTML, even if it isn't trying to take a stance. It's showing that core DOM spec can go a long way and is a bit of a bet on the Web being the future (VS using a different abstraction that compiles down to native). It doesn't have to be that way but that's how I perceive it's position today. Given Surplus really is just the render library and makes even less assumptions than React and is similarly functionally composable other than being unproven doesn't seem particularly better or worse suited for any specific type of application.

adamhaile commented 6 years ago

@ryansolid That's a great summary and very much in line with my thinking. Thanks for taking the time and writing at such length.