Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What are the downsides of preact? #2199

Closed
gc opened this issue Dec 21, 2019 · 15 comments
Closed

What are the downsides of preact? #2199

gc opened this issue Dec 21, 2019 · 15 comments

Comments

@gc
Copy link

gc commented Dec 21, 2019

Preact is advertised as much much lighter, and faster than react, to me it sounds like someone is offering you something that sound too good to be true. I am very interested in adopting preact, but I'm sceptical. So I'm just wondering what are the downsides to it over react?

@JoviDeCroock
Copy link
Member

In the docs we explain this difference: https://preactjs.com/guide/v10/differences-to-react

TLDR: We don't implement the synthetic event system of React-dom which saves a ton of size

Also:

  • We use a 1-Phase-render (we are going to transition to a 2-phase sooner or later)
  • Suspense and lazy are still experimental

@gc
Copy link
Author

gc commented Dec 21, 2019

Thank you. It's mentioned that a big chunk of the size difference is because of the lack of synthetic events, but I don't think it says what, in practical terms that actually means for our apps? Potential bugs/gotchas with certain old browsers? Having trouble with certain events?

@marvinhagemeister
Copy link
Member

Nope, not really. The cross-browser situation isn't as bad as it was during the old days where jQuery was the king of the web. The synthetic event system is a hard requirement if you're targeting environments outside of the DOM like native.

So far I've personally only come across some third party react components for rich text editing that relied on some react-specific implementations of certain events, but apart from that it has been smooth for me.

@just-boris
Copy link
Contributor

I have got issues when tried to create masked input with Preact: https://9x6wv.csb.app

In React, it can be solved via a very small piece of code: https://github.com/realadvisor/rifm
Preact does not manage the cursor position properly, which causes issues. (Should I create a separate report?)

@talentlessguy
Copy link

TypeScript conflicts. They can be solved partitially using a custom declaration but it won't be 100% compatible

@marvinhagemeister
Copy link
Member

@just-boris please file an issue for that. That way we can ensure that it will be fixed 👍

@yisar
Copy link

yisar commented Jan 7, 2020

Respectfully, I think the biggest difference between preact and react is the internal source code implementation, but not the APIs.

It's exciting that different data structures and algorithms are used within react, the implementation of preact is more like react 15, which lacks creative source code.

But unfortunately, react has not found any use cases that preact can't do the same, so from the user's point of view, react has no advantages.

Any way, time slicing, Suspense, useTransition, etc. are more meaningful in react, but not necessary at all.

In conclusion, I think that for users, preact can be smoothly compatible with react, but for source enthusiasts, react has more possibilities in the future.

@marvinhagemeister
Copy link
Member

It's exciting that different data structures and algorithms are used within react, the implementation of preact is more like react 15, which lacks creative source code.

I see this as a big advantage to be frank. Our source code is very straight forward without any heavy or needlessly complex abstractions. This makes our code very easy to change adapt and experiment on and has the very practical benefit that we have to spent less time on maintenance 💯

In conclusion, I think that for users, preact can be smoothly compatible with react, but for source enthusiasts, react has more possibilities in the future.

I agree in the sense that our code is very practical without any fancy abstractions or other things. This may put developers off who like more complex code. As a counter argument we often get the feedback from authors of other popular frameworks, that their virtual-dom implementation is heavily influenced by ours for the single reason that our code base is very understandable 👍

@yisar
Copy link

yisar commented Jan 7, 2020

This makes our code very easy to change adapt and experiment on and has the very practical benefit that we have to spent less time on maintenance.

If you don't need to be compatible with react, you are right, but it will become more and more difficult to be compatible with react, because the source code gap is widening and maintenance is becoming more and more difficult.

@marvinhagemeister
Copy link
Member

Nah, I don't see any signs of that. I think you're confusing API compatibility with the actual implementation. The API contract is the secret ingredient for compatibility, not the implementation underneath it.

@JoviDeCroock
Copy link
Member

JoviDeCroock commented Jan 7, 2020

I would disagree, implementation details have never been the goal of compatability, we offer users to have the same API and see the same result by using that API.

Coming to that result by time-slicing or whatever is trivial for a user, a user wants to see the UI, we optimise in different ways but get the same result.

What do you mean with not-creative? I see us straying away from it in many ways, don’t get the point there.

@yisar
Copy link

yisar commented Jan 7, 2020

@JoviDeCroock @marvinhagemeister

Well, I'll finish my point. However, React team will release more new APIs in the future, not only time slicing, Suspense and useTransition, which are not easy to be compatible.

You may say that all of these can be realized, but due to completely different data structures and algorithms, it will progress slowly.

@developit
Copy link
Member

@yisar I'm going to try to clear some things up here that stand out as potential misunderstanding.

First, I tend to believe that the difficulty of a task can be an indication in favor of its worth. For Preact, in addressing any gaps between renderer philosophies you alluded to here, we fill an ever-increasing need in the ecosystem. For developers who adopted React for design, preference or philosophical reasons, Preact provides a path forward that does not require them to also adopt React's new mechanics and direction.

To that end, I would like to suggest that no single project can set its direction such that it will continually satisfy all possible use-cases on a platform as diverse as the web.

There are many applications where Preact's minimal implementation is highly appropriate:

  • small and medium-sized applications
  • embedded content (avoiding the multi-actor problem)
  • applications where preact is not the primary means of rendering
  • mixed-framework applications (ex: Angular app with some React-style components)
  • server-rendered websites using Components for progressive enhancement

To get back to the original point, it's worth understanding that Preact is not a project to simply re-implement React using simpler internals. There are other projects dedicated to that objective, as you're aware given your involvement. Preact is actually quite the opposite - the team establishes its own direction and goals that guide our implementation. Compatibility with React is just one of those goals.

It's easiest to understand this using an example. Given the ideal use-cases I enumerated above, the Suspense mechanics Preact needs in order to be effective actually don't require scheduler-driven two-phase diffing. One of our goals is to enable progressive hydration for large trees: since hydration is a special-case where DOM is never mutated, Preact's goals do not currently require separate diff and patch phases. It's very possible that future use-cases may require multi-phase diffing, which is why @JoviDeCroock and others are exploring what that would look like in Preact.

I hope this doesn't come across as being defensive. We understand your point about divergence and how that scales into the future, it's just that this tradeoff is one the team makes intentionally. Sure it's difficult, but the difficult choices we have made are some of the reasons this project continues to provide unique value.

@yisar
Copy link

yisar commented Jan 8, 2020

@developit
First of all, thank you for your explanation.

As a framework, preact is great. I think I may be misunderstood. I want to say that the disadvantage of preact is compatibility with react. If compatibility is not considered, preact is perfect.

It's very possible that future use-cases may require multi-phase diffing, which is why @JoviDeCroock and others are exploring what that would look like in Preact.

From most use cases, multi-phase diffing can solve most of the problems, but I think the while loop of linked list and double buffering have irreplaceable advantages (fallback, break, continue, insert, remove), which is the difference of data structure between tree and linked list.

Although at this moment, I can't find convincing use cases other than time slicing.

There are other projects dedicated to that objective, as you're aware given your involvement.

It's worth noting that I just provide the idea of source code implementation, I don't care about users and usages. This is also a trade-off. I hope that others will pay more attention to the source code through my project.

@developit
Copy link
Member

developit commented Jan 9, 2020

No problem! Always happy to discuss these types of directional things. 👍 I got the feeling we were likely talking past eachother, and it actually sounds like we have pretty similar views.

I do think the data structure portion of this is interesting, but I've also done fairly extensive testing on the raw performance of higher-order data structures in JavaScript and was disappointed with the results. There are many cases where Linked Lists should logically be far faster than Arrays, but since JavaScript Arrays are quite different from those in other languages, they have specialized optimizations for common cases built up over years of evolution with little constraint over the underlying representation. I'll admit it's been a few years since I revisited this and I imagine engine changes have shifted the costs, though I'd be curious to know to what extent.

That's not to say I don't think you're right about adopting a more purpose-built data structure can be good long-term - I totally agree. However, this goes back to the pragmatism comment I made - it's very likely Preact's path forward will include changes like this (double buffering with opcode sequences). But because we've committed to delivering value in as few bytes as technically feasible, the project's goals demand that we hold off on landing those changes until it becomes measurably beneficial for the use-cases Preact caters to. For us that means extra work, as we have to create and maintain forked implementations in order to know when we cross that threshold, but it's something the team manages to keep on top of.

This is actually one case where I wish we had the equivalent of a "working group" for Virtual DOM implementors. I love discussing these types of things and I've experimented with wildly different approaches to this problem space that aren't represented in Preact since they either didn't pan out or didn't fit the model (or as you pointed out - differed too much from how VDOM currently works in React). I've been casually discussing some ideas for moving diffing and patching into the Web Platform itself, and this makes me wonder if one of the fringe benefits would be giving ourselves a forum for discussing shared optimizations and strategies between framework authors. Certainly something to think about...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants