WebReflection / udomdiff

An essential diffing algorithm for µhtml.

Home Page:https://medium.com/@WebReflection/the-web-smallest-dom-diffing-library-5b69ac4d1f4d

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can the algorithm be generalised?

titoBouzout opened this issue · comments

commented

@WebReflection I'm not even sure if this package is the current?, you have a million of packages xD

anyway, the question is: can the algorithm be generalized? This is also useful for merging stores, albeit I am not really that sure about that. Solid seems to use some versions, or modifications of this algo, in different situations and I am wondering if can be generalized, because I am currently dealing with the same thing, I need to patch the dom, and I also need to patch stores.
https://github.com/solidjs/solid/blob/dbdc27df2246ec05c0e32cf7b461ddbe4223915f/packages/solid/store/src/modifiers.ts#L3

maybe not all diffing, because this
https://github.com/solidjs/solid/blob/dbdc27df2246ec05c0e32cf7b461ddbe4223915f/packages/solid/src/reactive/array.ts
seems to come from
https://github.com/adamhaile/S-array

https://github.com/ryansolid/dom-expressions/blob/main/packages/dom-expressions/src/reconcile.js

Do you see any approach to generalise this problem?

Thanks!

@titoBouzout

I'm not even sure if this package is the current?

current ... about what? 😅 this package is the DOM differ for uhtml or others so it is the one I use and a tiny rewrite of the original domdiff for hyperHTML ... I am not sure what you are after though but the algo is described and generalized within the code itself ... and it works on SSR too so it is already generalized, but it uses DOM primitives such as removeChildren or insertBefore, so that bit might not be usable without DOM nodes, but it can work with splice pretty much the same way (so it can diff arrays).

commented

current ... about what?

Something that caught me off guard every time I look at your packages is that you have slightly similar packages, so I never know which one should I use. This last update was 4 years, and some updates in a new branch from a few months ago.

Well, I meant to generalize it in some sort of api, so it can be used by giving the function the methods for manipulation, as to make it work with more than the DOM.

This last update was 4 years

it's been rock solid ever since and it still scores the best string literal based DOM library out there in the classic js-frameworks-bench (faster than lit) and it still works like a charm since ... well, 4 years ago.

some updates in a new branch from a few months ago

the fast-path turned out to be an epic fail in practice because my assumption was that using less DOM APIs to change things stuff would've been faster, then I've benchmarked after the implementation and newer DOM APIs do more behind the scene so the result was both disappointing and slower ... that branch can be ignored, it's there just for possible future catches up if those APIs ever result into faster operations at the practice level.

I meant to generalize it in some sort of api, so it can be used by giving the function the methods for manipulation, as to make it work with more than the DOM.

It's a good hint but it means at least the following:

  • it will be a breaking change at the export surface, as the logic will be defined at runtime and not statically
  • I need to document it to explain all possible operations

After all this doesn't seem like a bad idea at all though so I will think about it and come up with something ... as this works since about ever and it's fast as hell and battle tested, I am afraid I don't have any urge to make that happen but if it turns out to be an easy-to-implement thing, maybe it's worth letting others explore the current algorithm for things that go beyond raw DOM nodes diffing ... I am intrigued myself by what that could be, but you've likely seen already every library has its own thing and it's hard to make it a de-facto standard for either DOM or other arrays operations ... still though, until I offer that, it's hard to tell if it could ever be successful and welcome future contributions to make it even better, whenever that's possible.

I hope this answers your question, I am going to flag this as feature request or something, if that's OK

commented

Thanks, Andrea, that's great. I will experiment and let you know, because right now I have to do both, dom patching and store (array and object) patching. So it will be pretty interesting to see if a generalized approach could be worked out.

the main thing that differs in the DOM as contract is that when you move nodes somewhere else, the previous tree, if live, automatically updates itself ... I can easily provide a 1:1 splice operation for new "parents" but if I have to notify all moved "nodes" parents too this can't be too fast and it will likely be problematic for store related things ... surely a runtime API that gives you a differ could have a dom field that's true by default and opt-into the extra work only for non dom operations, but benchmarks after implementation need to land carefully too.

Not a real blocker though, hopefully food for thoughts for your store use case.