I recently found that the drawing animation in one of my notebooks is noticeably slower and choppier than it ever has been before for me, both on the old and new Observable sites:
To create the animation effect, I followed the same logic as this example notebook (which does not appear to be any slower than before) that uses a for loop to step through frames and updates a “stroke-dasharray” attr to lengthen the dash to the corresponding proportion of the overall line length.
I know my notebook is more computationally intense than the example but I don’t think think that should account for the difference in smoothness. And as I said earlier, it was smooth in the past (see this Bluesky post of a direct screen capture for example).
Maybe there is an easy obvious fix I am missing, and if so would appreciate if anyone could point it out!
Thanks
Cool notebook and great question; we definitely want to keep a close eye on performance. And at first glance, I agreed with you that new seemed slower. If anything, new should be faster, since the app has been significantly streamlined.
I made a deterministic fork that removes randomness and restarts the same random walk animation every ten seconds (clock-synchronized, like 6:41:10 pm, 6:41:20 pm, etc.) and screen-recorded old and new side-by-side, comparing the miles traveled, and they look very similar to me. My clock sync isn’t perfect, so one sometimes starts 0.08 miles ahead of the other, but then it seems to basically stay 0.08 miles ahead (± 0.02 miles?) for the duration of the animation.
Does this screen recording match your experience?
This does make me think we need proper performance evals where we can objectively test for regressions.
Reflecting more… I honestly don’t understand the deep runtime internals very well, but I think that basically it consumes generators up to sixty times a second by requesting an animation frame. When your computation fits within the “budget” of one frame, it will max out yielding 60 times per second. When it doesn’t, we drop frames. If an animation is driven by the clock, it’d appear choppier; if it’s driven by an incremental computation on every frame, it’d proceed slower. I haven’t really studied your animation, but I think we should basically expect it to run at the same speed in both old and new. So the number of miles traveled isn’t really a benchmark for the performance of each. But we should design one…
Another thought. I use Chrome typically, but Observable Desktop uses Tauri, which (unlike Electron) uses the OS’s built-in browser engine to avoid the bloat of shipping yet another copy of Chromium, so it uses Safari (WebKit). And when I first started using Desktop I noticed many animations were choppier. It turns out that Safari has some rules where it doesn’t run a frame at full performance until it’s focused by the user. So, viewing a notebook in Safari, it gets faster the first time you click inside the notebook’s output (what we call the “worker” iframe, the rendered results of your code). So you may sometimes notice that…?
Hey Toph,
Thanks for checking on this and for that helpful background! Your video is in line with what I see on Chrome which is still slightly slower than it originally was (as shown in that post above) but not so bad. I naively hadn’t given a thought to the effect of browser choice on this, and I recently switched over to Firefox which is even choppier than Chrome, so that is probably a bigger part of what I was noticing than the Observable update.
Still raises the question of why the line chart animation is so quick in comparison, but I can keep poking around and see if there are any drawing or computation optimizations I can make along the way to help smooth things out.
Probably the biggest thing making the animation slow is that you are redrawing the entire map for each frame. It would be much faster if you just update the map incrementally (specifically the stroke-dasharray property) during the animation. That is easy to do in this case; here’s a suggestion.
Thanks, that’s painfully obvious now that you say it!
I appreciate you take the time to make that fork. 