There is a certain behavior of Html.Keyed.node
that I wanna try and fix up.
I’m hoping a complete Elm compiler recompile is not necessary to do that. Is there a more reasonable approach? Some flag that would allow me to use modified kernel code?
There is a certain behavior of Html.Keyed.node
that I wanna try and fix up.
I’m hoping a complete Elm compiler recompile is not necessary to do that. Is there a more reasonable approach? Some flag that would allow me to use modified kernel code?
This is the way I hack on the core modules:
ELM_HOME
to a folder local to the project I test on, so that I can modify things in there without messing up other projects.$ELM_HOME/0.19.1/packages/elm/virtual-dom/1.0.3/
.$ELM_HOME/0.19.1/packages/elm/virtual-dom/1.0.3/artifacts.dat
.elm-stuff/
.Doing all of that manually gets old very quickly, so I put all of that into a script to make it easier.
Btw, this summer I started working on elm/virtual-dom too – and the biggest thing I’ve got left in my project is Html.Keyed
. So I’m curious what things you’d like to improve around keyed!
This is awesome. Thank you sir!
It may be even more awesome that you’re already checking VIrtualDom.js
Here’s the behavior I wanna adjust:
insertBefore
or after
.The reason why this trips me up, is because I’m building an animations mechanism which hooks onto the DOM mutation calls using a web component. In the presented case, b and c, already animated into the view. By reinserting them through the document fragment, their css animation unexpectedly runs again.
What do you think?
Edit: I corrected the provided case in this later comment.
If you make a patch against elm/virtual-dom and submit it as a PR, it could be picked up by elm-janitor virtual dom fork: GitHub - elm-janitor/virtual-dom: The foundation of HTML and SVG in Elm.
Assuming the patch has no other undesirable side effects, it is likely a worthwhile bug fix to incorporate into the janitor, and sounds like it may even be more performant. I am not really sure why the keyed node code does not already work this way as it seems a logical approach to take, but on the other hand its quite a complex and fiddly thing to get right.
Once added to the janitor patch stack, there is a helpful script (GitHub - elm-janitor/apply-patches: Hacky script to apply the patches of elm-janitor) to install it, which basically automates overwriting the package in $ELM_HOME.
Cool, that definitely sounds like something that keyed should do! I’ll keep that in mind when I get back to working on keyed in my project.
Lydell, have you documented somewhere your purpose/goals for tinkering with the vdom?
Rupert, thanks, I doubt I’ll be comfortable enough to push to it, but let’s see : )
For now, the only place to read about it is the #elm-virtual-dom channel in the Incremental Elm Discord. Once I reach a more stable state, I will write things in more public places.
No worries. If you do put the code somewhere public, and it works well, I would happily volunteer some time to review it and make a solid PR out of it.
I need to correct my previous case.
If only a single element is inserted, then the anticipated wrapperEl.insertBefore()
is called.
The problem I described earlier happens when more than one element needs to be inserted. Example:
wrapperEl.appendChild()
is called with document fragment of [ “2”, “3”, “4”, “5”, “6”, “7” ]Additionally, I’m observing that any time that a DOM element is added to a document fragment, the element is being removed from the DOM, causing layout recalculation.
This may have a big impact on performance—I’ve been working on a pure Elm rich text editor for years, and whatever I do, it becomes horribly slow above 10K characters. It’s of course possible (perhaps likely) that I’m a lousy coder, but the DOM updates that the RTE is doing are precisely the kind that you describe (like inserting a letter in the middle of a text). If you can share your modified virtualdom.js, I’d be happy to check if it makes any difference here.
Fortunately for me, as I was digging through to understand the document fragment behavior, I was able to adjust my custom element to adapt to it, covering all my edge cases.
Great news for me, but this means that I’ll be able to push forward without needing to modify the VirtualDom.js
I’m leaving you with my analysis so far.
This sounds like an usecase for virtualized list (fake scrollbars, rendering only what the user sees + some safety margins). We needed to do that some years back in GWI when our spreadsheet had 10k+ cells - browsers really don’t like that large DOM trees. Give it less work to do is my suggestion.
I have some code here for virtual scrolling a text editor, in case it can help you:
There is a catch though. This is for fixed size font code editor. So I can accurately calculate the Y position of any line of text so calculating what is visible in the scroll window is trivial. For a RTE editor, I assume you may have different font sizes, which makes the virual scroll harder to do.
Thanks for making that video! It reinforced my understanding of how Keyed is implemented. Also, I learned something new – right-clicking on a node in the inspector and doing “Break on > subtree modifications” is awesome for debugging, I wish I’d learned that sooner!
Long time ago I wrote a few lines of code that would patch elm/*
packages from forks of those packages.
This approach should work for both fixing bugs in the core packages and for experimenting with the kind of stuff that is restricted to the core packages (operators, effect modules, kernel code).