Option to reconcile viewport labels only on zoom end - #1599
Conversation
✅ Deploy Preview for afmg ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Per-frame ViewportLayers.schedule() re-ran label materialization and the collision reflow pass on every guard-band escape, so long zooms and pans recalculated many times over. Mid-gesture the materialized content just rides the viewbox transform; the reconcile now happens once, when the gesture settles. A per-gesture flag tells a real gesture from a plain click: wheel gestures end on d3's idle timeout, after the last frame is consumed, so a pending frame cannot serve as the signal - and rendering on a click's zero-movement gesture would churn the DOM between mousedown and click dispatch and swallow the click. The new e2e drives a real wheel gesture, which setMapZoom-based tests cannot cover (d3 dispatches their end synchronously).
8a4d7e4 to
32eb403
Compare
|
The viewport reconciliation mid gesture is for a smoother transition and it actually looks nicer when labels pop up mid transition more naturally, not all at once at the end. And if we want them to only render at the end of transition, we can just remove a single line, we don't need the I tested the preview, it looks much worse for me, especially on zooming out. |
I think this might be something I can live with for now on my fork as a short term performance improvement. I do not believe it is adding value to AFMG based on your statement. I will continue to explore ways to improve efficiency and will take this design direction on baord :) |
|
@barrulus, it can be made optional. We have optimizedRendering boolean, but it can be a whole set of options for users. So some may toggle mid-transition rendering off for a slightly better performance. It's a tradeoff. I would like to have it on by default, but some users like options |
ok, has there been any work opn deciding what options to make available to users? |
No, but instead of a generic mode, we can make each option a separate one named based on what it actually controls. Check how it's used now. |
Currently every guard-band escape during a zoom or pan re-runs label materialization and the collision reflow pass, so a long gesture recalculates the labels many times over. Mid-gesture the already-materialized content just rides the viewbox transform, so those intermediate reconciles buy nothing visually - this moves the reconcile to the end of the gesture, running it once.
Two pitfalls shaped the implementation (both learned the hard way on my fork, which has been running this change):
frameId !== nullfreezes labels for every human-paced gesture. A per-gesture flag set in the zoom handler tracks the change directly.The included e2e drives a real wheel gesture via
page.mouse.wheel. That matters:setMapZoom()-style programmatic zooms dispatchendsynchronously while the frame is still pending, so they cannot detect the frozen-labels failure mode - the existing suite stayed green through it.Verified: label materialization after a wheel gesture is identical to the per-frame behavior on the same seed (headless comparison),
tscclean, 378/378 unit tests, new e2e green.