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

Compress to a single-pass #84

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

botandrose
Copy link

@botandrose botandrose commented Dec 24, 2024

This PR attempts to improve the algorithm further by removing the second pass. Rather than moving nodes to the pantry, and then back in later, it moves them to the correct place all within the first (and only) pass.

Note that this is an evolution of the v0.4.0 two-pass algorithm, and is behind the same option, so default mode still behaves like v0.3.0, and one must still enable the new algorithm via the twoPass option (which has become a bit of a misnomer).

Benefits:

  1. No more need for the abstraction-leaking beforeNodePantried callback. If you are doing interesting things with any of the other hooks, e.g. data-turbo-permanent, you'd often need to prevent the pantrying process from flattening the node trees that entered it, and thus you'd need to know how the internals of the pantrying process worked, and that there was a pantrying process at all, for that matter. This PR removes the hook, and the need for it.
  2. Hooks are called in the order one would expect, and with the arguments one would expect. Two-pass mode resulted in minor changes to both in v0.4.0. This PR results in hook behavior that is more correct than both v0.3.0 and v0.4.0.
  3. Many minor suboptimal situations have become optimal. For more details, see the test changes in the diff.
  4. Less DOM operations than v0.4.0, so maybe more performant?

Finally, as far as I can tell, there are no downsides to this new approach, but I welcome any skeptical scrutiny to make this as good as it can be! Can we find any regressions from v0.3.0 or v0.4.0?

P.S. First two commits are from #83 , which is a bugfix and should be evaluated separately from the outcome of this. I'll rebase once that gets merged.

@@ -208,7 +205,7 @@ var Idiomorph = (function () {
// innerHTML, so we are only updating the children
morphChildren(normalizedNewContent, oldNode, ctx);
if (ctx.config.twoPass) {
restoreFromPantry(oldNode, ctx);
ctx.pantry.remove();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when two pass is off ctx.pantry is just a dis joined div so we can just call remove() on it every time to simplify the code

@@ -365,12 +365,17 @@ var Idiomorph = (function () {

// if we are at the end of the exiting parent's children, just append
if (insertionPoint == null) {
// skip add callbacks when we're going to be restoring this from the pantry in the second pass
if (
ctx.config.twoPass &&
ctx.persistentIds.has(/** @type {Element} */ (newChild).id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here if twoPass is false the persistentIds is an empty set so it may be possible to remove the twoPass config check here as well. There could be a very small perf hit to check has on an empty set here but its probably not measurable either way.

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.

3 participants