question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

The road to Preact 11

See original GitHub issue

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 the Portal 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 compat

Whilst 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 the vnode tree, but there are some remaining ones that still rely on the DOM itself. This is made more difficult by the existence of Fragments.

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:

  • Add fast path for single child elements
  • Store DOM operations in an effect queue (aka centralize paints)
  • Add fast path for mounting

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.

// Element with two Text nodes
<div>Hello {name}</div>

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 keeping ref in props. If we keep it in there we can make all forwardRef components redundant:

// Current way
const Foo = forwardRef((props, ref) => <div ref={ref}>{props.children}</div>);

// Proposal
const Foo = props => <div ref={props.ref}>{props.children}</div>;

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 with Portals. 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.

// This is not possible currently
<TreeA>
  <Foo />
  <root>
    <TreeB />
  </root>
</TreeA>

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.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:157
  • Comments:82 (28 by maintainers)

github_iconTop GitHub Comments

112reactions
developitcommented, Jul 12, 2020

2kb 2kb 2kb

64reactions
38elementscommented, Jul 12, 2020

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Differences to React - Preact
What are the differences between Preact and React. This document describes them in detail.
Read more >
Preact (@preactjs) / Twitter
The journey to Preact X began on a quiet evening in October 2017. ... that 2022 will bring some amazing things, we've been...
Read more >
PreACT Practice Tests: Where to Find Them and How to Prep
... year as an 11th grader. Most importantly, however, prepping for the PreACT is simply a great way to familiarize yourself with the...
Read more >
Preact - Releases
Preact - ⚛️ Fast 3kB React alternative with the same modern API. ... Fix tests in IE11 (#3264, thanks @developit); Add jsx(-dev)-runtime to...
Read more >
Preact - What Is It & When to Use It? | Codete Blog
Functional components making use of hooks are now the preferred way to write React components, as well as component error boundaries (fault-resilient components) ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found