Open marvinhagemeister opened 4 years ago
I think that it is better that Preact 11 stops support IE11 and Edge which is not based Chromium. Preact X will continue to support these brower.
I think that it is better that Preact 11 stops support IE11 and Edge which is not based Chromium. Preact X will continue to support these brower.
Good idea! We should definitely drop the requirement to work out of the box with IE11. This would allow us to use Map
or Set
objects. IE11 users can always polyfill those. Regarding Edge: Admittedly we never had any bigger problems with it if I recall correctly. Ultimately we need to see what kind of code base we'll end up with, but I have a feeling that supporting old Edge browser doesn't require any changes on our part.
Regarding Edge: Admittedly we never had any bigger problems with it if I recall correctly.
It may be unimportant thing, there is #2331.
2kb 2kb 2kb
@developit mentioned plans for better supporting server-side-rendered HTML that stays at least partially functional even without JS (I found HEY inspiring here). Any details on those plans yet?
@rauschma The main things we have explored related to that are actually implemented using Preact X as it exists today, so I'd put them on an independent timeline from a Preact 11. The reason for this is that anything related to HTML ends up requiring that folks use (more) specific server-side techniques, versus the current simplified renderToString() approach.
I'll try to prioritize at least publishing some of the exploratory work and demos we have. It's less impactful than providing an off-the-shelf fullstack framework, but that's probably fine given the highly variable nature of Preact usage.
Some very interesting ideas here Marvin, thank you for airing them and thanks to the preact team generally for all their hard work on 10.x. I have committed this year to building preact apps almost exclusively and it has been a pleasure; the tools, the community, everything is like a breath of fresh air.
One thing I am wondering about the future of preact however, is, will it always try adhere to the react API? Being ~ its namesake and given all the effort that went into increasing ecosystem compatibility in X, I assume the answer to this is yes. But I am curious, if you happened to stumbled across a potentially useful new primitive or feature outside of the react API.. would it be considered?
I've been inspired recently by the likes of hyperapp and svelte with their effect and subscriptions APIs respectively. Do you see any promise in these kind of interfaces specifically, or are the team content that these kind of behaviours can be encapsulated by hooks?
Some very interesting ideas here Marvin, thank you for airing them and thanks to the preact team generally for all their hard work on 10.x. I have committed this year to building preact apps almost exclusively and it has been a pleasure; the tools, the community, everything is like a breath of fresh air.
Thank you so much for the kind words! It's comments like these that keep us motiviated! :heart:
One thing I am wondering about the future of preact however, is, will it always try adhere to the react API? Being ~ its namesake and given all the effort that went into increasing ecosystem compatibility in X, I assume the answer to this is yes. But I am curious, if you happened to stumbled across a potentially useful new primitive or feature outside of the react API.. would it be considered?
We will keep compatibility with the React API for the foreseeable future, but it's very likely that we'll put our own spin on thinks more in the future. Keeping ref
in props
and thereby removing the need for forwardRef
is one small step in that direction.
I've been inspired recently by the likes of hyperapp and svelte with their effect and subscriptions APIs respectively. Do you see any promise in these kind of interfaces specifically, or are the team content that these kind of behaviours can be encapsulated by hooks?
Personally, I fully agree that a simple subscription primitive is very appealing and something I've played a lot in the past and shipped a few projects with. We see a lot of code in the wild where re-renders are triggered for the sole sake of triggering effects. Not saying that this bad code, but rather that hooks tend to lend itself to that usage and I'd love to welcome different ideas to Preact. So far reactivity is a leading contender to do that in my opinion.
That said we'll always try to keep that part pluggable like now as there never is a silver bullet approach and different applications require different trade-offs. One neat library that uses RxJS as a first class option to manager state for Preact components is bassdrum. There is also #1923 which adds a vue-like composition API on top of Preact as another alternative to hooks.
So yeah I see a lot of value in these concepts and we do want to make it easier for those systems to directly plug into Preact in the future. Hooks are a great approach for local state but they're by far not the only one. Our devtools extension barely uses hooks or classes for that matter for example.
@developit Having something lightweight in that space would be very welcome!
I see that the new size calculation standard is to calculate the size of Hello world project. After tree-shaking, it seems that there is no need to pay for the class API.
In addition, does the diff algorithm, which is detached from DOM, mean that it is completely detached from DOM, and vdom does not contain DOM information? If so, it would be great. I'm looking forward to itο½
In addition, does the diff algorithm, which is detached from DOM, mean that it is completely detached from DOM, and vdom does not contain DOM information? If so, it would be great. I'm looking forward to it
The way vdom works is that it always needs a reference to the underlying element. There is nothing that says that this has to be a DOM node though and that can be leveraged for different renders. There is more work to it than that on the road to support custom renderers, so it may be that we lay down the groundwork in v11 and add offical support for it in v12.
There is a way that no need underlying element, such as https://github.com/Matt-Esch/virtual-dom, It's very primitive, but it can be used as a reference. It's a completely DOM independent approach, and is well suited for cross platforms.
Good point, I stand corrected! Creating "patch" objects and push them in an effect queue is something we thought about too. It's something where we will likely experiment more with it after Preact 11 or when we rewrite our reconciler.
Thanks for your response above @marvinhagemeister π
We will keep compatibility with the React API for the foreseeable future, but it's very likely that we'll put our own spin on things more in the future
This sounds sensible and I can't wait to see what our own spin ends up looking like!
I had never heard of bassdrum so will have to check it out, also https://github.com/preactjs/preact/pull/1923 looks very interesting. Keeping things pluggable seems like a good idea too. Very much looking forward to v11 now! Keep up the good work and thanks again for your insight and explanation.
@marvinhagemeister I have never worked with Preact, But i happen to pass by this repo. And you can already see what I'm doing!
This is fresh, This is oxygen. I know React is mainstream, but only because it came up with the idea of components i guess.
You guys are doing awesome work. I found React very FB sided, instead of being a true OS project. They work on what FB wants(i mean that's ok) but still, thats not how OS should work.
I love React by all means, but that direction ain't fair. You guys will rock soon.
Mark my words.
Keep at it. β€οΈ
@sauravkhdoolia Thanks for the kind words :heart: We share your enthusiasm and can't wait to see what's next :+1:
I think preact needs a reverse complement of preact/compat, either at runtime or as a codemod. Right now, there's little incentive to use the preact namespace instead of react. As evidence of this, i think the stars to dependent projects ratio is a good indicator, maybe think of it as an adopt-ability ratio. Lower is better. Preact 1.03 @ 26.7k/23k Vue 0.15 @ 169k/1.15m React 0.04 @ 153k/4.10m Angular 0.45 @ 62.5k /1.39m Svelte 1.66 @ 35.7k / 21.5k
If developers could use preact without fear of not being able to switch to react, i think adoption rates would be much higher, which will allow preact to not only compete for a larger chunk of the open-source mindshare , but also to allow people to actually use deviations from the react api.
Since most browsers support Brotli, I think it may be better to focus size compressed by Brotli, not gzip at Preact 11. https://caniuse.com/#feat=brotli
For me the top priority is performance, I don't care about React compatibility at all. Most used mode is drop in bundle with HTM as I am doing embedded apps on really small devices with just about 4 MB storage. Preact 10 is already good but if it can be better with 11 then I'm all in.
I think that it is better that Preact 11 stops support IE11 and Edge which is not based Chromium. Preact X will continue to support these brower.
Good idea! We should definitely drop the requirement to work out of the box with IE11. This would allow us to use
Map
orSet
objects. IE11 users can always polyfill those. Regarding Edge: Admittedly we never had any bigger problems with it if I recall correctly. Ultimately we need to see what kind of code base we'll end up with, but I have a feeling that supporting old Edge browser doesn't require any changes on our part.
My two bits here:
I for one appreciate the ie11 support, if you remove this, it will be harder to argument for Preact vs others due to lack of browser support (especially in bigCorp settings where ie11 is A LOT more common than the whole www).
if you remove it, you'll have to do some heavy lifting to assure that simple polyfilling makes preact ie11 compatible with end-2-end test suites and how-to's that work.
could we move to htm and have it compiled out on build instead of vhtml by default (and save a few kb on the post build size) ?
About IE11, dropping it will allow the codebase to evolve, ship less and better code for modern browsers.
Maybe it could be possible to create a IE11 compat layer? I think Vue was heading in that direction.
Now that Microsoft has dropped IE11 support officially, I'm very much in favor of doing so too :+1:
To be precise, Microsoft also drops Edge (legacy).
wish: optional DeepEqual comparison in useState, keep the default Shallow Eval, and an optional Deep Eval.
const [ getter, setter ] = useState({DeepObject}, {deepEval:true}).
Iβd like to see hooks exported from the Preact core module. For most node modules, sub modules are not supposed to be used directly.
import {
h,
useCallback,
useEffect,
useErrorBoundary,
useLayoutEffect,
useReducer,
useMemo,
useRef,
useState,
} from 'preact';
@remcohaszing Really curious about where it's not supported. Can you share more details?
It's really unlikely that we'd ship hooks in core, much more likely that we will move Component out of core.
Subpackages are going to become commonplace over the next couple of years, since they're now specifically supported and recommended by Node.
If I may add my question here. Preact has been phenomenal at React feature parity and I assume same for Concurrent Mode.
So, should we anticipate CM in Preact 11?
@osdevisnot No, we currently have no plans to support Concurrent Mode. It's still up in the air whether CM is something that benefits apps at all, even for React. The current implementation in React breaks most state management libraries: https://github.com/facebook/react/issues/15317#issuecomment-716554673
Most of our current focus is on progressive hydration, faster SSR and lazy loading things.
I read a number of comments on supporting IE 11 and I think it might be a good to consider having two production builds for browser usage using type=module | nomodule
. For example:
<script type="module" src="preact@11.0.0/dist/preact.min.js"></script>
<script nomodule src="preact@11.0.0/dist/preact.nomodule.min.js"></script>
Recently I have done this a lot more myself in some projects and and just minimizing the source files using terser and then creating the legacy browser build using Babel/webpack. When I've done this the code size on the compressed module builds is smaller and in my opinion much cleaner because classes and other modern syntax are kept.
In the past there was an issue with browsers fetching both module and nomodules and with a specific version of Safari 10 (widely used work around available) and Legacy Edge but as of December 2020 the percentage of users using browsers that double fetch looks to be less 0.05%
; granted for a high traffic site that result with large number of users but I've been testing double fetching of recent nomodule|module
code I've written and am finding it to not really be much of an issue.
If considering this though, one important item to be aware of is there are a still a lot of widely used older modern browsers that support ES6 and type="module"
but do not support newer syntax such as the the Spread Syntax ...
. Example include UC Browser
wikipedia link which is widely used in Asia and older versions of Samsung Internet (widely used everywhere).
If you consider dropping IE 11 you would be in good company as Bootstrap 5 (currently in Beta) is dropping IE. Additionally Vue 3 shipped without IE 11 support (it's planned) but after 3 months it's not ready and made a lower priority.
Hello everyone π. Update from the core team:
As part of our v11 efforts, we have started a restructure of the Preact codebase. Inspired by some of our internal experiments and other frameworks, we believe it is time to restructure our renderer a bit. With this restructuring we are looking to improve its approachability and maintainability, as well introduce some new constructs that will enable new features we'd like to explore further (e.g. improving Suspense support, progressive hydration). Further, our internal experiments have shown some perf improvements from the changes we have in mind. Help us make Preact faster by contributing some stats about your App. Details of these changes will come in the descriptions of the PRs as they happen, but in general, the big one we are currently working on is separating the code paths for mounting and hydration from the code path for diffing.
This restructuring happen on the restructure
branch. You'll start to see some PRs opened against that branch as we make progress on reworking the renderer. At this time, we are only considering non-breaking changes in this branch with a plan to release this rewrite on the v10.x release line. As we get closer to the next 10.x release, we'll provide more details on a roadmap.
At a later point, we'll create a branch for v11 which will contain the breaking changes we are planning for that release. If you are interested in participating in that discussion, check out the open PRs in the preact/rfcs repo where you can discuss and propose breaking changes and provide feedback.
As we work on this change, you might see our bundle size and perf numbers fluctuate. This fluctuation is expected as we explore different approaches we may take. However, know that staying small and fast is still our end goal.
More details about the restructuring itself will come with each PR into restructure
. Until then, hit the subscribe button on this issue to stay up to date with v11 progress.
Hello there π as somebody interested in switching to Preact I'd like to provide my personal wishlist for it, hopefully it will be somewhat useful to the maintainers here.
TL;DR: The best library is the smallest, the fastest, the cleanest, the best documented, the most bug-free etc. Preact is already so small, it doesn't really matter if we can get it down to 2kb rather than 3kb, there are other dimensions that maybe should be improved upon.
@fabiospampinato Unfortunately to tell you this is impossible. Because React does not have integration testing at all, React only has unit testing, which only tests theoretical behaviors. The implementation details of preact and react are completely different, and the testing of react cannot be used.
@yisar I'm not familiar with React's test suite, isn't something like this fairly end-to-end?
With enough patching Preact should be able to run these, the internal unit tests we don't care about, it doesn't matter if they don't pass.
https://github.com/facebook/react/tree/master/packages/react-reconciler/src/__tests__/
React has very few e2e tests, but more unit tests. Its main purpose is not to test the rendering "results", but to rendering "process". This does not apply to preact.
I don't know there seem to be a decent amount of them under react-dom, the tests regarding internal details of React's reconciler we don't really care about I guess, overall React is a fairly robust and well tested library right? I would be very surprised if they don't have enough integration tests, you can't just unit test something complicated and hope for the best. Do we think exactly 0 of these tests Preact would fail? Would being able to run some of these tests with both libraries reveal exactly 0 performance issues? It seems unlikely to me, maybe the effort to make this work isn't justified, but I'm skeptical that it would be effort spent completely in vein. Maybe there are better ways to spot the remaining compatibility bugs, I'm not sure what those would be.
Hey @fabiospampinato
maintainer here, we often look at the output tests of React when we are solving a discrepancy so I do solemnly agree with you that we could do more of this, thank you for your input π
Regarding Edge: Admittedly we never had any bigger problems with it if I recall correctly.
It may be unimportant thing, there is #2331.
You should really use onChange most of the time anyway, it's decidedly more a11y friendly
Hello there π as somebody interested in switching to Preact I'd like to provide my personal wishlist for it, hopefully it will be somewhat useful to the maintainers here.
Running React's own test suite and reducing failing tests as much as possible.
- Currently the most important feature of Preact that enables it to gain a lot of new users is compatibility with React, this compatibility isn't perfect though, in order to get it as close to perfect as possible I think it would be a good idea to be able to run React's own test suite with Preact to see exactly where the incompatibilities are.
- If the test suite output would be made available online it would also be somewhat useful for documenting exactly where the incompatibilities with React are.
- Being able to run the same code with both React and Preact would also provide a decent benchmark suite, it wouldn't be perfect, but it would be useful for spotting some performance gaps between the two libraries.
- I personally tried to switch to Preact and had to revert the change because a dependency I have became buggy after the migration.
Ensuring almost everything is at least as fast as React's equivalent implementation if not faster.
- Being 10x smaller is awesome, but if that comes at the expense of runtime performance, even in a limited set of relatively common use cases than switching is no longer a no-brainer. Basically shaving X ms from startup is great, but if that comes at the expense of wasting Y extra ms every second at runtime, where Y is not approximately 0, then maybe the cons start to outweigh the pros for many use cases.
- When I tried switching to Preact performance seemed decent enough on my machine, but for example I took some measurements while scrolling a list in a loop, and switching to Preact made the whole thing ~20% slower and introduced some visual glitches. I'd expect Preact to be at least just as fast as React in almost every case, and hopefully faster in many cases since here we can modernize the library somewhat by breaking away from React slightly (no custom event system, maybe removing legacy code for IE etc.).
Exploring potential build-time optimizations.
- There seem to be some untapped potential in the form of build-time optimizations, the React folks don't seem to be willing to explore that path, partially because of concerns regarding bundle size increases, IMHO build-time optimizations can be strictly an improvement and we should have some (worst case scenario if they aren't in some cases or the transform is not quite sure it could just bail out of them, or the average Preact user might be just more performance-savvy and able to make these decisions themselves).
TL;DR: The best library is the smallest, the fastest, the cleanest, the best documented, the most bug-free etc. Preact is already so small, it doesn't really matter if we can get it down to 2kb rather than 3kb, there are other dimensions that maybe should be improved upon.
You say the perf dropped? That's weird, cuz in my case, the perf increased like crazy. My app uses a lot of heavy animations, which would cause some heavy jank. Switching to Preact actually got rid of that. https://puruvj.dev/blog/moving-macos-from-react-to-preact-vite#Runtime-performance
You say the perf dropped?
@PuruVJ Navigating a list in my app using Preact takes about 20% more computation compared to doing the same thing with React, yeah. That's just a fairly narrow thing though, which people won't notice anyway, other than that I haven't looked enough into it to say anything precise about Preact's performance overall, it seems alright so far for my use case.
You say the perf dropped?
@PuruVJ Navigating a list in my app using Preact takes about 20% more computation compared to doing the same thing with React, yeah. That's just a fairly narrow thing though, which people won't notice anyway, other than that I haven't looked enough into it to say anything precise about Preact's performance overall, it seems alright so far for my use case.
Fair enough
I wonder if between new rendering restructuring and this
Store DOM operations in an effect queue (aka centralize paints)
it will be possible to create a shallow renderer that is not going to depend on DOM and therefore will not require jsdom
or other DOM implementation for unit testing.
Definitely still want to be able to transpile at least to an ES5 bundle and load it instead if the browser doesn't support ES6 features.
Vue 3 is completely dropping IE support due to it using the ES6 Proxy object for reactivity which is language level and its behavior cannot be polyfilled.
changed my mind on this, after microsoft is kicking ie11 down the road, i think this should be dropped aswell
idk if I'm in the minority on this one but I just had to abandon Preact (which I was excited to use!) because getting the types to work with the React libraries I was using was just untenable (emotion
in particular was a big sticking point). it seems like all the published solutions involve doing deep surgery on preact/compat
's existing types, effectively kneecapping typescript by enabling skipLibCheck
for the whole project, or both. More robust support for type-level interop in Preact 11 and beyond would be really great!
@mprast never had typings issues with preact and other libs. Could you please provide a repro? Curious what you are dealing with.
Even though I'm a happy user of preact
, my personal frustration in preact
is with hydrate
method with both SSR and prerendered html (prerendering was done in the same browser and environment that does CSR), but it's hard to share a repro for the unstable work of hydrate
, so I decided using render
is good enough for my use cases.
@mprast did you have @types/react
installed? I installed it and it works perfectly
@o-alexandrov @PuruVJ let me give it another shot - very possible the issue was on my end. If it doesn't work I'll put up a repro
If you install @types/preact, your class
might stop working. To fix that, add this snippet to your types.d.ts inside the src
folder
declare namespace React {
interface HTMLAttributes<T> {
class?: string;
}
}
With Preact X being a great success there The 10.x release line was all about increasing ecosystem compatibility and the initiative was a complete success. Compared to Preact 8.x there are many more third party libraries that work out of the box with Preact, we saw the addition of Fragments, hooks, a revamped devtools extension, prefresh for native HMR support and much more.
In summary, we learned a ton the past year whilst maintaining Preact X and we want to push Preact even further. So the next question for us is: Where do we go from here? What should a successor look like?
This is a collection of some of our thoughts, but is in no means a concrete feature list for Preact 11. Please keep that in mind.
Size reductions
Our small (smol?) size has always been one of our strong points and the thing I'm personally the most proud of. With an ever growing feature-set we're currently very close to the 4kB mark and would like to bring that number down again. Whilst we may be able to shave of a couple bytes here and there, I think we won't have substantial changes on that front without thinking critical of each feature.
Only include what's actually used
The most common talking point is that many projects (including preact-devtools) don't use a single class component. The natural question that arises here is why we need to still pay for the cost the class API regardless. Ideally only the features that are actually used should be shipped to users.
The same is true for
preact/compat
which will always include side-effects even though a user may only needs to import to thePortal
component for example. There have been some attempts to do that in the past, but to me it seems like some changes in core could make that easier.The overall motto should be: Only include what's used.
Move
IS_NON_DIMENSIONAL
to compatWhilst it sounded cute on paper it has turned into a growing list of properties (see #2608 ) which is something we never wanted to have in core. The reason we kept it over from the 8.x line in core, was that it allowed us to keep old codepen demos working. This was especially useful at a time where we weren't officially committing to Preact X and we were more just playing around with various approaches.
I'd even go so far as to consider it harmful as I've seen it confuse new developers first-hand when switching between writing CSS and declaring inline styles. It's a feature we cannot remove entirely because of React, but moving over to compat should be fine.
Reconciler performance
Whilst the original plan for X was to break from using the DOM for traversal and only use the
vnode
tree for that, we ended up in the a little bit awkward middle ground. Most operations walk thevnode
tree, but there are some remaining ones that still rely on the DOM itself. This is made more difficult by the existence ofFragments
.For our next generation we should cut ties with our past and completely base it on the
vnode
tree instead. The newly added statistic metrics reveal some great places to look for improvements. Some of the ideas that are currently floating around:The effect queue idea is in particular interesting as it would the browser to batch all paint jobs and process them at once instead of having those intertwined with running JS. Heck we could make a lot of the DOM pointer code easier by applying those changes right-to-left instead of left-to-right.
What's more is that having an effect queue would open up the possibility for custom renderers. It's a long shot and not something we'll focus on in the near term, but we would at least have the possibility to do so nonetheless.
Boosting hydration
We're already in a good position when it comes to hydration performance but we have a lot of ideas what we can do to make it even faster. Any optimizations we'll do on our reconciler will directly benefit hydration, so there is a very close connection between the two.
Besides reconciler performance, there is a need to re-evaluate how we can best boot up from SSR'ed content. Due to us not joining adjacent text nodes anymore we have a mismatch during hydration. SSR'ed HTML will always create a single text node, even if it was created from multiple ones.
An alternative to joining adjacent text nodes is to insert HTML comments as markers in-between them. Not sure which approach is ultimately easier, although my gut tells me that the latter can easily become complex.
Remove the need for
forwardRef
The introduction of the
forwardRef
component is mostly a workaround for not keepingref
inprops
. If we keep it in there we can make allforwardRef
components redundant:There is a downside to that though in that there may be custom runtime checks in third-party libraries that explicitly check for additional properties in the
props
object. We ran into some of those in the past if my memory serves me well, and I'm secretly hoping that the increasing adoption of TypeScript has improved the situation compared to a few years ago.Mark root nodes as roots
Both the devtools and
Portal
component would benefit from having a way to place sub-trees into existing ones. Currently no tree knows about the others which leads to some weird edge cases withPortals
. There has been fantastic work during the 10.x release line to get it stable and I feel like we can make that code easier by having a special branch for root nodes as sub-trees in our reconciler.If we follow that thought further we could theoretically even look into switching renderes on the fly if there is any attached to the root node. A use case for that would be to switch to rendering into a canvas element somewhere in the middle of the tree.
What else can we do?
The above list is already a lot of work and will keep us busy for months but there may be stuff I've missed. Again, the points mentioned here is a collection of ideas and not a definitive feature set for Preact 11.