tl;dr: This release contains several important improvements to our reconciler (the part that is responsible for moving the DOM nodes around). Because of that we highly recommended everyone who is on one of the previous alpha releases to upgrade.
Easter is coming up, and we have enough changes in master
to warrant a release π During the past weeks we managed to resolve lots of bugs. Not just your standard bugs, but loads of the trickier ones π For the first time in a long while we are below the 100 issue mark π With release we feel confident that it can be used in a wider target audience. Our featureset is complete, and we even added a lot more than was initially planned for Preact X. If you're missing something where you feel like that it must absolutely be added in the initial release and can't wait for the next minor one, please voice your opinion in our issue tracker.
Fragments
considered stable
The most notable change is a very welcomed refactoring of our reconciler to fix known issues we had with Fragments
. @andrewiggins spent a lot of time the last weeks on getting this one right. What's most impressive about this is that he didn't just fix one or two of the issues surrounding Fragments
, and instead blew us all away by squashing all of them in one go.
In classic Andre fashion the PR is very thorough with detailed annotations about the changes in each commit. He just has that incredible talent for stepping back and assessing the situation with fresh eyes.
Demo inspired by https://codepen.io/JavaScriptJunkie/pen/pPRooV
Next-level conditional rendering
One cool optimization that our new code base allowed us to do is introducing the concept of placeholders (often referred to as "holes") in our renderer. These placeholders allow us to skip a bit of work when updating conditionally rendered elements like in the following example:
<div>
{condition && <Foo />}
<h1>Fasterπβ‘</h1>
{!condition && <Bar />}
<p>vroooooom π</p>
</div>
Seeing that this is quite a common pattern in Preact-based apps, we are very excited about the performance improvements of that technique. Another positive side effect is that it opened up the chance to land further enhancements to keyed and unkeyed children!
Depth-based component updates
Once thing that was bugging us, is that even with version X, Preact would do more work than necessary when nested updates are involved. This happened when a child component enqueued an update via setState
and later one of the parent components does the same thing, we'd render the child component twice (Child -> Parent -> Child
). This happened because we would process the queue in the order the updates where added. We can effectively remove a whole render by making our processing depth-aware. Our new code detects that we can optimize the ordering by rendering the parent first which will automatically update the child component.
This work was initially started by @JoviDeCroock and later joined by the whole team. We're quite happy with the result and noticed the enhanced rendering speed in our own apps π―
Official adapter for enzyme
For a while now @robertknight has devoted his time to greatly enhance our testing story. He wrote an adapter for the popular enzyme testing library from Airbnb. It even works with both Preact 8.x and Preact X. We've been using it quite a bit in our own projects and wanted to mark it as an official package.
At some point in the future we're planning to move all the other libs over to the organization, too. But there is no concrete timeline available for now. The main benefit for us the org provides is a shared permission model for contributions so that we don't have to bug @developit each time we make a PR to our offspring libraries like preact-router
and preact-render-to-string
.
Status: Bundle size
With this release we have surpassed the total bundle size of the 8.x line. Due to improved tree shaking the hello world example will be smaller though. Depending on how the future will unfold we may put more focus in the next weeks on finding ways to cut down on size π€ This is a lot easier to do with an extensive test suite like we have now π Stay tuned!
Without further ado, here is the full changelog:
Bug Fixes
- Keep track of childDom between
diffChildren
calls (#1515, thanks @andrewiggins) - Remove getFirstOldDom (-42 B) (#1531, thanks @andrewiggins)
- Add support for arrays with holes as placeholders (#1440, thanks @marvinhagemeister)
- Apply state updates based on depth (#1534, thanks @JoviDeCroock)
- Fix incorrect depth ordering (#1536, thanks @marvinhagemeister)
- Fix nodes with different keys being reused (#1532, thanks @marvinhagemeister)
- Fix stale DOM with async preact-router (#1539, thanks @marvinhagemeister)
- Fix Portals not being unmounted (#1537, thanks @marvinhagemeister)
act
should be able to track and flush the full queue and all subsequent queues (#1520, thanks @JoviDeCroock)- Fix error with component attributes that start with
on
(#1530, thanks @JoviDeCroock) - Remove
prop-types
dependency (#1525, thanks @natevw) - Add clear button to demo logger (#1517, thanks @marvinhagemeister)
- Add
_depth
to mangle.json (#1542, thanks @38elements) - Remove unnecessary code (#1543, thanks @38elements)
Typings
- Use same type naming as @types/react (#1519, thanks @marvinhagemeister)