-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Bypass props during hydration #1697
Conversation
Love the direction this is going! This way of special casing some attributes looks a lot cleaner 👍 The first test failure seems to be a test case that needs to be updated for the changes in this PR. The other one may likely be only related to a different ordering in the assertions. I vaguely remember having swapped the attributes assertion order last time I touched |
Played a bit with the changes in this PR and it looks like event handlers won't be attached anymore on hydrate. Made a new test case for this and it works on it('should attach event handlers on hydrate', () => {
let spy = sinon.spy();
scratch.innerHTML = '<span>Test</span>';
let vnode = <span onClick={spy}>Test</span>;
hydrate(vnode, scratch);
scratch.firstChild.click();
expect(spy).to.be.calledOnce;
}); |
857f71b
to
0e7b352
Compare
FYI: Rebased it against |
Added this to project board since it fixes #1719 |
af877fa
to
d397916
Compare
@developit I'd love if you can take another look at the recent changes. To be able to attach event listeners during hydration we need to call Note: Rebased the branch against the recent changes in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome stuff! 😄
Looks like this adds +7B
? https://travis-ci.org/preactjs/preact/builds/549021011#L1692
if (i!=='children' && i!=='key' && !(i in newProps)) { | ||
setProperty(dom, i, null, oldProps[i], isSvg); | ||
for (i in newProps) { | ||
if ((!hydrate || typeof newProps[i]=='function') && i!=='value' && i!=='checked' && oldProps[i]!==newProps[i]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marvinhagemeister idea: check for i[0]=='o' && i[1]=='n'
instead? it should be ~free.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried that but it's +8B
bigger
175e871
to
7656005
Compare
Rebased and the byte size is only up by |
7656005
to
274a048
Compare
274a048
to
317d49a
Compare
This fixes a couple things that end up being best done together:
instead of special-casing the
multiple
prop by applying it before diffing other props, it leverages the fact that preact already special-cases thevalue
andchecked
props. Pulling these out intodiffElementNodes()
ensures they are applied last.during hydration (
excessDomChildren==null
), never calldiffProps()
. This makes it so that Preact no longer diffs attributes and props at all during hydration - previously only unknown attributes were ignored, but for performance reasons and to match other VDOM libraries it's worth also not diffing known attributesdon't diff children when a node has dangerouslySetInnerHTML applied. This avoids the case where you have a node with both dangerouslySetInnerHTML and children specified, which previously would continually remove children. The solution in this PR probably doesn't correctly unmount children when transitioning from JSX children to dangerouslySetInnerHTML. This could perhaps be fixed by having the existence of dangerouslySetInnerHTML for a VNode assign
vnode._children=[]
.styles: this should be a bit of a performance optimization for styles. It's hard to verify, but I think I'm seeing some relatively consistent numbers in the perf tests showing this to be the case. I'd originally made the change in order to fix the style issue someone reported this week (can't find an open issue about it for some reason)