Skip to content
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

Introduce implicit keying #191

Merged
merged 1 commit into from
May 1, 2023
Merged

Introduce implicit keying #191

merged 1 commit into from
May 1, 2023

Conversation

chinedufn
Copy link
Owner

This commit introduces implicit keys to siblings that are being diffed.

This was introduced to solve for the following case:

start: <div> <span><input /></span> </div>
end: <div> <img /> <span><input /></span> </div>

Before this commit, if the input in the above example was focused at
the start, it would lose its focused after the patches were applied
since the span would have gotten replaced by the img.

Now all elements with the same tag are implicitly keyed such that
the diffing algorithm will send up generating patches that will move
elements instead of replace them, when possible.

Note that there is a cost to this, since the longest increasing
subsequence algorithm that we're using to diff keyed siblings is
`O(n log n).

This commit makes it such that n will always be the number of child
elements, now that all child elements have either an explicit or
implicit key and will all pass through our LCS pass.

Note that the n is the number of siblings across the chldren of two
different nodes, not the number of nodes in the entire dom tree.

So, for most realistic use cases n should be relatively small, since
most use cases don't have large lists of sibling nodes.

This commit introduces implicit keys to siblings that are being diffed.

This was introduced to solve for the following case:

```text
start: <div> <span><input /></span> </div>
end: <div> <img /> <span><input /></span> </div>
```

Before this commit, if the `input` in the above example was focused at
the start, it would lose its focused after the patches were applied
since the `span` would have gotten replaced by the `img`.

Now all elements with the same tag are implicitly keyed such that
the diffing algorithm will send up generating patches that will move
elements instead of replace them, when possible.

Note that there is a cost to this, since the longest increasing
subsequence algorithm that we're using to diff keyed siblings is
`O(n log n).

This commit makes it such that `n` will always be the number of child
elements, now that all child elements have either an explicit or
implicit key and will all pass through our LCS pass.

Note that the `n` is the number of siblings across the chldren of two
different nodes, not the number of nodes in the entire dom tree.

So, for most realistic use cases `n` should be relatively small, since
most use cases don't have large lists of sibling nodes.
@chinedufn chinedufn merged commit 6cf0c0c into master May 1, 2023
0 of 2 checks passed
@chinedufn chinedufn deleted the implicit-keys branch May 1, 2023 17:51
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.

None yet

1 participant