Feature request: React-style reconciliation

Are there any thoughts on implementing React-style DOM reconciliation on cell rendering? I imagine this is sort of complicated but I could imagine benefits—particularly animation benefits:

  • Cells with a lot of elements might be more efficient to rerender if not every node needs to be recreated each time—might enable more complex animations that use Observable’s reactivity (though only if the diffing algorithm didn’t eat up the performance savings)
  • Could animate elements using CSS transitions + Observable reactivity, if for example an element changed class but Observable was able to identify that it was the same element with a new class

I imagine this is non-trivial to implement, but I’m wondering if it’s something Observable is thinking about.

1 Like

Hi Harris, you can use react inside observable, so any components the need the performance you mention can use react to render? https://observablehq.com/@j-f1/react so when the cells updates, react will handle the dom updates as needed.

Otherwise, for most data viz notebooks, I never found the dom nodes re-rendering an issue, in fact using canvas in the yield and drawing the whole thing rather than using an existing canvas also works perfectly smooth for most notebooks at a good fps.

Yeah, I’ve looked at that React notebook a bit! I tried to use it a bit, but found it a little clunky (layering Observable’s reactivity on top of React’s reactivity made it a little confusing for me to decide which one to rely on for updating particular components, etc.), but I should give it another go now that I have a better understanding of Observable.

The example I’m thinking of where performance has been an issue is a county-level U.S. choropleth that I’d like to animate over time. It’s just a lot of SVG shapes to rerender every frame. I imagine switching to canvas would make it smoother, but it would introduce some code complexity. I might give that a try though. :sweat_smile:

Hi @harris,

Another option that might work really smoothly for your use case is to work with D3’s new selection.join feature.

You can minimize DOM operations on large SVG visualizations where every element isn’t changing at once, and also animate the enter, update and exit states:

It would be great if one of us (or one of you oh-so-helpful folks on the forums) wrote a little example showing how to use selection.join on a map with many counties, states or countries…