nerv icon indicating copy to clipboard operation
nerv copied to clipboard

What's the tradeoff?

Open mxstbr opened this issue 6 years ago • 26 comments

The readme and website make a bunch of extraordinary claims ("same api, much faster, better browser compat, smaller bundle size"), but what are the tradeoffs of choosing Nerv vs vanilla React? What do I miss when I choose Nerv?

Note: Not trying to be a pain in the butt here, genuinely curious why React wouldn't just take this code base and make it their own

mxstbr avatar Jan 10 '18 20:01 mxstbr

Just to underscore @mxstbr's point, you lose nothing by documenting the tradeoffs honestly. If your users have to discover those tradeoffs themselves, they won't trust the project anymore, and they will have a very easy time switching back to React, given the API compatibility.

benjamn avatar Jan 10 '18 21:01 benjamn

I'd like to see this project runs against the official React test suite, to have a quantifiable measure of knowing how closely this implementation matches official API behavior. If it passed 100%, and offered superior performance / reduced file size, I would be excited to use this.

petermikitsh avatar Jan 11 '18 04:01 petermikitsh

I think no 10kb-or-so-react-alternative would have async per frame rendering like React 16 have. Splitting rendering into job chunks that fits 16ms frame isn't that easy. This probably the biggest trade off of every React alternative now. Until R16 it wouldn't be much problem.

dzek69 avatar Jan 11 '18 09:01 dzek69

Sorry for the late response.

I would love to add tradeoffs to README. In fact, I have been make a public talk in China to explain How and Why we build a another React-like library, there is also a Chinese article in this repo's wiki posted weeks ago: 《为什么我们还需要一个 React like 框架?》 (In English: Why we need another React-like library?), which compares several React-like library(preact, Inferno), React itself and Nerv.

But as you can see, I'm not good at English, translations takes time. After I finish README.md and home page translation last night, just feel exciting (it was not easy for me to do this) and submit to Hacker news and reddit.

I apologize for the misunderstanding for some words in README, later there might be some change after we consult with some colleagues who is good at English. For now, there is some background about React, React-like library and Nerv:

React

The bottom line is: You should use React while you can use React.

Just forget about all React-like libraries (including Nerv) advertising about how fast they are, the key of performance is about the guy who write the code, not about the library or framework. If performance really that matters to you, you should consider manipulate DOM directly like VSCode did.

If you like the idea of React, but can’t use it for some reason (like Apache, or IE8, size), you should consider choose a React alternative:

preact

Preact is the most popular React-like library, as they describe: got everything your need. The author Jason Miller is very active in GitHub, maintaining the repo. It looks perfect for a React replacement. But there still some problem we don’t satisfy.

First, preact just so obsessed about the size, every PR must be small, some (we think) important feature/fix would’t merge because it takes too many code. We fork a preact in the beginning for internal project because preact would’t allow the size of it over 3Kb gzipped.

And there is performance issue. If just use preact alone that’s fine, even faster than React in several benchmark. But in our scenario, we use third-party React library a lot, so preact-compat is required. preact-compat will transform a preact element to a React compatible Element (such as change prototype descriptor ), there is huge impact in performance, you can test by aliaing preact to preact-compat in any benchmark.

Inferno

Inferno is my favorite React-like library, when the company decide make our own React-like library (at the time React is not MIT license), I was thinking: “Inferno is the way how I implementing a React”. To be honest, Nerv learn a lot from Inferno, diff algorithm, event delegation, etc. Thanks to @trueadm and his great work, if wasn’t for Inferno, Nerv couldn’t make so far today.

As you can imagine, Inferno also can not be satisfied with our requirements. It just because Inferno doesn’t wanna be a React replacement, they has their own ecosystem, such as inferno-router . As I assume, they just want a extremely fast library, React-like is a bonus point. To achieve the target, there will be some compromise, such as you can’t use react-router in Inferno, because React will continue diff when the type, props, context and the reference of old vnode and new vnode are the same, instead, Inferno just quit diff when old vnode and new vnode shared a same reference.

Nerv

In my humble opinion, The biggest difference between preact, Inferno, and Nerv, is not some technical issue like what’s the right way to implementing a React feature. It is about the what does the library want to achieve. In preact, maybe they just want a lite library, Inferno want to be fast as they can, React compatibility just a bonus, they are both need a compat module to do that. But for Nerv, compatible with React is our main goal, by doing that, we can sacrifice performance and size.

Peter Mikitsh’s criticism is right. Nerv can’t pass React fiber(16) 100% unit test, which is predictable —— the React team takes whole year to achieve the target, how can two guys come from nowhere(says by some guy in Hacker news) be able to do that?

So, What’s the tradeoffs? Obviously, some third-party React component/library couldn’t work properly in Nerv. But which one? To be honest I don’t know. I’m glad to be heard that Next.js next-news worked on first try., but in the meantime, Benchmark tabs don't work in Firefox (fixed) —— All of this, We wouldn’t know if we don’t go public.

Rome wasn't built in a day. Nerv is not perfect, no library is, particularly in early stage, maybe there still tons of bug we don’t know. Therefore we decided to open source, to go public, we need the community’s help, we need your help. Of course you can sit there and do nothing but complain about this or that(like me doing it now), or you can submit a issue even a PR, tell us how can we make Nerv better. With community’s help, such as [feature missing] (https://github.com/NervJS/nerv/issues/17) , [typo fixed] (https://github.com/NervJS/nerv-website/pull/3), I believe after couple month later, Nerv will be much stronger and smarter —— Perhaps this is what open source about: we help each other, we do things together.

Hope this reply answers your question.

yuche avatar Jan 11 '18 11:01 yuche

That is an incredible response, thank you so much @yuche for taking the time to type that out! Again, no hard feelings at all, I totally understand that language can be a big barrier. :heart:

Have a great day!

mxstbr avatar Jan 11 '18 12:01 mxstbr

Thank you for your reply. So to sum this up the main goals of Nerv are 100% compatibility, free as in freedom license and IE8 support. The trade off is not being well-tested yet and it may not pass all unit tests from React, but are you going to to achieve that as well?

Personally I think this is very interesting project and I'm soon going to publish small isomorphic webpage and I'm obsessed with file sizes as well, but preact forced me to use compatibility package even when I thought it shouldn't be necessary and I'm not satisfied with that. I'll try to use Nerv instead.

dzek69 avatar Jan 11 '18 12:01 dzek69

Can we maybe have some numbers? Benchmarking?

sospedra avatar Jan 11 '18 13:01 sospedra

@sospedra There are a few benchmarks on the website main page - https://nerv.aotu.io/

popey456963 avatar Jan 11 '18 13:01 popey456963

@mxstbr Thanks for point it out that we do really need a tradeoff description. A good question like this could be very useful to sort things out. I going to reopen this issue. Any question or criticism is welcomed.

yuche avatar Jan 11 '18 14:01 yuche

@sospedra Yeah, we will show the benchmarks ASAP. You can see the results at https://nerv.aotu.io/ first.

luckyadam avatar Jan 11 '18 14:01 luckyadam

@yuche thanks for the detailed response

If you like the idea of React, but can’t use it for some reason (like Apache, or IE8, size), you should consider choose a React alternative:

On the 'like Apache' note specifically, that refers to React's previous BSD licence. I believe it has moved to MIT.

ColinEberhardt avatar Jan 11 '18 18:01 ColinEberhardt

Good job, this library is necessary. I feel pained at seeing all the comments on HN and /r/javascript talking about how React is "fast enough" like some kind of stockholm syndrome.

Charuru avatar Jan 11 '18 19:01 Charuru

How come there's no Inferno comparison listed in the benchmarks section of the website? Seeing as Inferno was/is leading the pact, shouldn't a comparison against it be listed as well?

davedbase avatar Jan 11 '18 19:01 davedbase

@ddibiase Hi there, a little bit shame to say this is intentional as far as I know (as their colleague), because Nerv can't really beat inferno LMAO (still can outscore inferno-compat though). But they are going to commit all the benchmarks and you will soon see inferno on the list.

chuyik avatar Jan 12 '18 02:01 chuyik

I didn't see the website. My fault. Pretty impressive numbers I'll definitely take look by myself soon.

sospedra avatar Jan 12 '18 07:01 sospedra

Don't rely so much on benchmarks people. Benchmarks often doesn't resemble real world use cases. A lot of them is even written to favour one of the alternatives, by testing these features that works best in one library and not caring about more important features that are way too slow in favoured library.

Until all libraries aren't tested with several independent benchmarks - don't get too excited about library being 20% faster in some benchmark, because in your application it may be 20% slower.

dzek69 avatar Jan 12 '18 07:01 dzek69

Agree with @dzek69 tho, in what we rely then? In opinions? Benchamarks are not perfect but they provide a way to compare differente frameworks. Ofc, always use differente benchmarking strategies and compare different frameworks results under the same method. We won't get accurate absolute numbers but probably we'll get a ver accurate comparison between them.

sospedra avatar Jan 12 '18 07:01 sospedra

Thanks for your work in nervjs, @yuche. Besides including Inferno.js in the benchmark, may I suggest also including Dio.js?

https://dio.js.org/

rosenfeld avatar Jan 12 '18 18:01 rosenfeld

@dzek69 While true in general the benchmarks I saw were all third party. I'm especially interested in the results of this bench by ebay where nerv did very well: https://github.com/NervJS/nerv/issues/16

Charuru avatar Jan 12 '18 21:01 Charuru

@yuche thanks for your reply, though I still don't really get it. You've correctly identified that the React-like alternatives out there each have carved out a niche such that they can coexist with React in the Javascript ecosystem because they satisfy differing criteria, and they all openly acknowledge their shortfalls.

It looks to me like you've acknowledged that the only shortfalls of Nerv are that it does not yet pass 100% of React's tests. Therefore you're not really advertising a React alternative, you're actually touting a WIP React successor, because you're implying that once you've passed all those tests you'll still have the same performance/filesize/compatibility benefits. What makes you confident that will be the case?

ryami333 avatar Jan 14 '18 08:01 ryami333

@ryami333 I think nerv is based on inferno, but it has better compatibility and sacrifices some performance. Is my understanding right? @yuche

loadingwyn avatar Jan 28 '18 05:01 loadingwyn

@loadingwyn @ryami333

What Nerv really doing is that learn from (we think) the most properly way to fulfill our goals. Like diff algorithm, I believe the credit goes to ivi, and many library are using it, like surplus.js, DIO.js etc. The first version of Nerv using virtual-dom (you can see it in commit history), but we find out that ivi’s algorithm can reduce DOM manipulation by using prefix/suffix and LIS algorithm, so we switch to ivi’s algo. The reason of using TypeScript and Lerna is that they provide a better way to maintain our codebase and test, and I already describe it in #2 (In Chinese sadly).

Implementing a library just like choosing one, there are tradeoffs. For example, when you using React but using it wrong, in React, you got a nice warning or error. But in almost all React-like library(including Nerv), you probably got nothing, because we are trying to reduce the size of library.  And that’s also the reason that why we will never be able to pass all React unit tests, some of tests expect throw a error, we don’t have that.

As I said that before, use React while you can use it. The React core team did some truly incredible job about developer experience and building community. I have not doubt that React core team are able to continue support IE8 or score higher performance, but I guess supporting IE8 is unnecessary in developed countries like USA, but in China, there are considerable device are using Windows XP and IE8. And diff algorithm, React core team answered in #10703.

So what Nerv really can do is support React-related libraries/components as much as we can. We are planing support Material-UI and enzyme in next few weeks, hopefully Nerv can pass all Material-UI tests. (But now we are busy to handling company's Chinese new year event, and there is also ten days vacation after new year). And we are implementing our open source UI components as well, it’s like Material-UI, and work with both Nerv and React. After taking so much from the community, it’s time to give it back.

yuche avatar Jan 28 '18 16:01 yuche

Got it! Thanks for your reply. Is there any react's feature you don't and won't support definitely?

loadingwyn avatar Jan 29 '18 10:01 loadingwyn

@loadingwyn React Fiber and React Native. I afraid we will stick with stack reconciler instead of fiber. And React Native, we don't have the man power (native developer) to support that. 😞

yuche avatar Jan 29 '18 11:01 yuche

#2 translated.

t47io avatar Feb 13 '18 17:02 t47io

@dzek69

I think no 10kb-or-so-react-alternative would have async per frame rendering like React 16 have. Splitting rendering into job chunks that fits 16ms frame isn't that easy. This probably the biggest trade off of every React alternative now. Until R16 it wouldn't be much problem.

I did an alternative implementation of 1kb, instead, it is just easy.

https://github.com/yisar/fre

The difficulty in how to use better algorithms in this puzzling coroutine scheduling, such as the LIS algorithm of nerv, it is difficult to reduce the number of hits of the O(nlogn) branch in the data structure of the linked list.

Similarly, since the singly linked list has no back pointers, the both-end algorithm of snabbdom cannot be used, unless we give up the O(n) complexity.

https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactChildFiber.new.js#L760

yisar avatar Dec 11 '20 03:12 yisar