Skip to content

WIP: Add support for Fragments#1080

Closed
marvinhagemeister wants to merge 16 commits into
preactjs:masterfrom
marvinhagemeister:fragments
Closed

WIP: Add support for Fragments#1080
marvinhagemeister wants to merge 16 commits into
preactjs:masterfrom
marvinhagemeister:fragments

Conversation

@marvinhagemeister

@marvinhagemeister marvinhagemeister commented Apr 28, 2018

Copy link
Copy Markdown
Member

This is really rough draft, but I thought to develop more in the open to get the ball rolling. The last test is still failing and the code feels really hacky, but hey it's a start 🎉

Fixes #946 .

Comment thread src/component.js Outdated

});

/** Fragmetn is a "passthrough" component which only has the key attribute

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelled wrong 😉

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for spotting this :)

@coveralls

coveralls commented Apr 28, 2018

Copy link
Copy Markdown

Coverage Status

Coverage remained the same at 100.0% when pulling 4e2c553 on marvinhagemeister:fragments into 8be9c5f on developit:master.

@marvinhagemeister

Copy link
Copy Markdown
Member Author

Tests are passing, even for array returns 🎉

Still need to figure out a cleaner to integrate all this.

Comment thread src/vdom/diff.js
}
}
else {
updateChild(dom, child, f);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likely a small performance loss, because updateChild is not inlined anymore. Need to measure this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compared with master my measurements don't show much differences. The empty diff test shows the most difference.

master branch
empty diff 89503/s (30 ticks) 84007/s (31 ticks)
repeat diff 11707/s (228 ticks) 11373/s (228 ticks)
large VTree 43276/s (62 ticks) 43877/s (58 ticks)
style/prop mutation 19974/s (133 ticks) 19745/s (132 ticks)
SSR Hydrate 1384/s (1962 ticks) 1364/s (1903 ticks)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the slowdown of the empty diff check. Problem was the Array.isArray check at https://github.com/developit/preact/pull/1080/files#diff-a0896fa5d65b1d80ca4d496badbae50fR106

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how did you run those tests?

Comment thread src/vdom/diff.js Outdated
}

if (Array.isArray(vnode)) {
return vnode.map(x => idiff(dom, x, context, mountAll, componentRoot));

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Don't rely on Array.map

test(<div><Comp /></div>);

expect(scratch.innerHTML).to.equal('<div><span>foo</span>bar</div>');
});

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Add test for keyed Fragments

@marvinhagemeister

Copy link
Copy Markdown
Member Author

Decided to remove straight array returns, because they are making everything needlessly complex. Just using Fragments for this leads to the same result, so introducing the additional complexity is not worth it.

@staeke

staeke commented Jun 16, 2018

Copy link
Copy Markdown
Contributor

Any news on this? Is it only awaiting approval?

@tzvc

tzvc commented Jun 28, 2018

Copy link
Copy Markdown

Any update on this guys ?

@ergunsh

ergunsh commented Aug 1, 2018

Copy link
Copy Markdown

Any update?

@arusanov

arusanov commented Aug 6, 2018

Copy link
Copy Markdown

Any news?

Comment thread src/vdom/diff.js
if (parent && ret.parentNode!==parent) parent.appendChild(ret);
if (parent) {
// append the element if its a new parent
if (ret instanceof Array) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jsperf.com/instanceof-array-vs-array-isarray/33

can you try ret.constructor === Array?
its seems faster on many browsers
(you have two other instances of this in this file)

@Ayc0

Ayc0 commented Sep 1, 2018

Copy link
Copy Markdown

@marvinhagemeister there is an issue with your PR: line 203, in the code, there is originalChildren = dom.childNodes, but has you mutate this NodeList when there is an array of VNode, the components aren't mounted in the right order
you can see that the behavior changes by replacing this line with originalChildren = Array.from(dom.childNodes) (which duplicates the nodelist)

@Ayc0

Ayc0 commented Sep 1, 2018

Copy link
Copy Markdown

Without Array.from:
image

With Array.from:
image

@Kanaye

Kanaye commented Sep 1, 2018

Copy link
Copy Markdown

Hi @Ayc0.
It's unlikely that this PR will be merged into preact.
As per @marvinhagemeister comment on #946:
There is already a mostly working version on a private repo for the next preact major version.

@marvinhagemeister If my assumption is right, can we close this pr with a comment/link to your comment in #946 ?

@Ayc0

Ayc0 commented Sep 1, 2018

Copy link
Copy Markdown

@Kanaye perfect then 👌

@marvinhagemeister

Copy link
Copy Markdown
Member Author

tldr; Fragments are part of the next major release 🎉 🎉

Sorry for being radio silence on this PR.

We do have merged Fragments into out private repo for the next major version of preact. Although work had already started there, I tried to shim Fragments into the current architecture against all odds. Unfortunately it didn't work out. This PR has issues when holey arrays or nested Fragments which is not easy to fix.

Our current architecture relies on a 1:1 relationship between a vnode and a dom element. Fragments obviously break that assumption. This and other features that we always wanted to implement were the reasons why we went out to rethink our core architecture.

@Kanaye yep this can be closed 👍

@Ayc0 you're right. Array.isArray is faster than instanceof Array now. It's awesome how much browsers have improved on that front 👍 Also good catch on the mounting issues. These are a bit tough to fix with the way preact currently works.

@benjamin-schneider

Copy link
Copy Markdown

Hi @marvinhagemeister, any chance to have a date for this next major release ? I searched on the whole website but did not manage to find this information. Thx

@marvinhagemeister

Copy link
Copy Markdown
Member Author

@benjamin-schneider No we don't have set our eyes on a specific date. We're getting closer and closer each week but it's hard to predict an actual release date from that. Rest assured that all the hard work has been completed and we're currently working on getting all the ecosystem tools up to date (devtools, debug, render-to-string, etc).

You're right that this information can't be found on our website.

@edimitchel

Copy link
Copy Markdown

I waiting this feature too!
Thanks you for your amazing work !

@Eli-Nathan

Eli-Nathan commented Jan 7, 2019

Copy link
Copy Markdown

Any updates now on the date for the next major release?
This feature would save me right now 🙏

@marvinhagemeister

Copy link
Copy Markdown
Member Author

@Eli-Nathan just tweeted an update on the current state of Preact X: https://twitter.com/marvinhagemeist/status/1082329232322252800

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.