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.

Difference in DOM diffing compared to React

See original GitHub issue

I noticed this different behaviour in reconciliation between Preact and React. Here are the 2 demos:

Instructions: Click on the button to see the difference. Preact: https://codesandbox.io/s/61nk3p4z1r React: https://codesandbox.io/s/mymwzvnx28

Split component add a resizable gutter through out-of-react dom changes. In React, the dom changes stay after state changes (on pressing the button). Whereas in Preact, they vanish. I believe Preact’s behavior is correct, but not sure 😐 Thoughts?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:12 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
developitcommented, Nov 5, 2018

The diff is supposed to skip elements not created by preact, but it looks like changes in 8.0 added a way for that to be bypassed. Specifically, originalChildren points to the complete list of Element childNodes without any filtering to include only nodes created by preact. During child reordering traversal, we access this list based on index without passing over externally created nodes. That results in the “gutter” div in this split.js library being removed here:

https://github.com/developit/preact/blob/377e31b5c6d42c4ca92085571d5d4f0c9dbe4ba2/src/vdom/diff.js#L245

The issue is, innerDiffNode can’t use a filtered Array of Nodes in place of its current .childNodes reference, because we rely on the semantics of it being a Live NodeList. For now, that means something like this will be required:

function innerDiffNode( .. ) {
    let offset = 0;  // stores childNodes offset due to skipping

	// replacing L245
	f = originalChildren[i + offset];
	while (f != null && !isHydrating && f[ATTR_KEY] == null) {
		offset++;
		f = originalChildren[i + offset];
	}
	// now we know `f` isn't an externally-created node
1reaction
marvinhagemeistercommented, Aug 12, 2019

Closing, I can’t reproduce the original issue anymore with the code in master 🎉

Read more comments on GitHub >

github_iconTop Results From Across the Web

Reconciliation - React
When diffing two trees, React first compares the two root elements. The behavior is different depending on the types of the root elements....
Read more >
How Virtual-DOM and diffing works in React - Medium
Compares the previous internal instance with the next internal instance. Updates the internal Instance which is a Component Tree structure in ...
Read more >
React, "Diffing" and the DOM - DEV Community ‍ ‍
"Diffing". The process of checking the difference between the new VDOM tree and the old VDOM tree is called "diffing". Diffing is accomplished ......
Read more >
Understand Keys, Virtual DOM, Reconciliation, and Diffing in ...
When diffing children of a DOM node, React compares children of both lists and generates a mutation whenever there's a difference.
Read more >
React's Diffing Algorithm - JavaScript in Plain English
According to its publicly available documentation, React uses a method called the diffing algorithm to compare the old DOM to the new.
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