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

Include Reconciliation Functions #2

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

Include Reconciliation Functions #2

wants to merge 2 commits into from

Conversation

wlib
Copy link
Contributor

@wlib wlib commented Sep 5, 2021

Reconciliation in this context refers to the process of updating the DOM to match a given model of it. This is exactly what a virtual DOM does for the entire real DOM tree it controls - however, bruh already uses a better approach for the vast majority of DOM manipulation needs.

Conditional renders and updates (for individual nodes and attributes) are easily implemented with Reactive's. Anything more complicated than that is usually in the realm of managing multiple children, which is trivial to handle correctly with native DOM methods like before, prepend, append, after, remove, replaceChildren, replaceWith, &c. These methods are both intuitive and optimal for performance.

The classic React approach of building up a new array of children that gets diff'ed and patched is ironically less declarative and expectedly less efficient than the imperative alternative for the majority of cases. This is just because the majority of DOM manipulation is inherently imperative given that many UI's are intuitively modeled as state machines. However, there are certain cases where it is desirable to simply declare an array of children as the current state and automatically reconcile the DOM to match that declared state.

This is "keyed" child reconciliation, and is most useful for complex changes like list sorting and filtering. It really is most applicable here when creating nodes is expensive compared to running a diff algorithm. Otherwise, it might actually be more efficient to simply parent.replaceChildren(newChildren). Given that the need for reconciliation algorithms is relatively rare, it should be reached for only in the cases where it makes sense. Sometimes, using the right diff algorithm is actually both the most intuitive and performant solution.

Compared to the typical virtual DOM approaches, I intend to have reconciliation as a set of functions that are imported and used directly as needed. Virtual DOM libraries typically use one-size-fits-all algorithms that work decently for the general case, but bruh has the option to provide a collection of algorithms, each accomplishing the same function but optimized for different expected cases. For example, we can have algorithms that tradeoff time and space complexity, algorithms that specialize with uniquely-keyed children or allow duplicates, or run extremely well with few changes, or the opposite.

Of course, the default algorithm will just perform alright for general use - but bruh has the advantage of being able to provide options. If the DOM eventually gets native functions to help alleviate the root of this need (avoid unnecessary node state resets), then the scope of this part of bruh can be reduced and simplified, but it probably will still be needed to a degree.

@wlib wlib added the enhancement New feature or request label Sep 5, 2021
@wlib wlib self-assigned this Sep 5, 2021
@dy
Copy link

dy commented Sep 10, 2022

Hey.
Not sure if that will be to the point, but there's https://github.com/luwes/js-diff-benchmark comparing various differ algorithms.
Within them I'm the author of swapdom (spect) and I believe that has very fine and the most compact/simple diffing strategy.
I found it useful in multiple places, I wonder if you consider it meaningful here.
Cheers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants