Reduce reads of dom.nextSibling#2294
Conversation
|
Size Change: +40 B (0%) Total Size: 38.2 kB
ℹ️ View Unchanged
|
| parentVNode.type !== 'tfoot' && | ||
| parentVNode.type !== 'tbody' && | ||
| parentVNode.type !== 'table') | ||
| parentVNode.type !== 'thead' && |
There was a problem hiding this comment.
This is how Prettier formatted this for me 🤷♂
|
|
||
| outer: if (oldDom == null || oldDom.parentNode !== parentDom) { | ||
| parentDom.appendChild(newDom); | ||
| nextDom = null; |
There was a problem hiding this comment.
Since we are adding newDom to the end of parentDom, newDom.nextSibling will always be null. So instead of going through the DOM APIs to get this, I'm precalculating it here so save us a DOM read.
| } | ||
| } | ||
| parentDom.insertBefore(newDom, oldDom); | ||
| nextDom = oldDom; |
There was a problem hiding this comment.
Since we are inserting newDom before oldDom, newDom.nextSibling will always be oldDom so I'm precalculating this now to save us a DOM read.
| let Foo = <div />; | ||
| let fn = () => render(h(<Foo />), scratch); | ||
| expect(fn).to.throw(/createElement/); | ||
| expect(fn).to.throw(/JSX twice/); |
There was a problem hiding this comment.
This test was giving a false positive because my change caused it to throw a different error that contained createElement when it should've been throwing this error. Caught this by looking at the code coverage and noticing that the line under the condition I changed was no longer covered lol.
* Reduce calls to nextSibling for nested Fragments/Components (+5 B) * Rename _lastDomChild to _lasDomChildSibling (-1 B) * Precalculate nextDom for append and inserts (+6 B) * Fix debug vnode type checking Co-authored-by: Jovi De Croock <decroockjovi@gmail.com>
While exploring ways to use
getDomSiblingto replacenextSiblingindiffChildren, I discovered that_lastDomChildshould really be_lastDomChildSibling. The only thing our code uses_lastDomChildfor is to determine what DOM node the diff should continue with after diffing a Component/Fragment.However when Components/Fragments are nested (like the example below) each Component reads it's child's
_lastDomChildproperty and reads thenextSiblingproperty. If the Components are the last child of their parent's (like the example below), then thisnextSiblingread is redundant to the read that it's child already performed. Note: it's only useless when the Component is the last child because the result ofoldDom = newDom.nextSiblingis thrown away. In diffChildren,oldDomis only used to determine what DOM the diff should use for siblings. When the Component doesn't have any siblings, the value ofoldDomis thrown away and_lastDomChildis used instead in the parent.In other words, what we really want to bubble up while diffing Components/Fragments isn't the last DOM child of the Component, but what DOM should the diff continue with. So this PR changes
_lastDomChildto_lastDomChildSibling.I also used this change to precalculate what
oldDomshould be in situations where we know it without having to readnextSibling