What could explain this apparent slowdown on Firefox when using d3-geo projections with React.js?

23 Views Asked by At

I'm completely stumped by this, so please let me know if I should tag this differently or post elsewhere - also please let me know if you need more information.

I'm working on a project using React and D3. Specifically, using the d3geo package. I have a projection defined with

const projectionFunction =

d3[projectionName] || d3GeoProjection[projectionName]; let projection = projectionFunction().reflectX(true).clipAngle(90); useLayoutEffect(() => { projection.scale(projection.scale() * scale); }, [scale, projection]);

This works well. Whenever scale changes (which I change through the d3.zoom event handler), the projection function works as expected and "zooms" in.

const zoomed = useCallback(function zoomed(e) {
    const { k } = e.transform;
    setScale(k);
  }, []);
let zoom = d3.zoom().scaleExtent([1, 8]).on("zoom", zoomed);

Additionally, I have a function that rotates the projection, and the rotation is changed by the d3.drag event handler.

function onDrag(e) {
      setRotation((cur) => {
        return [cur[0] - e.dx / (6 * scale), cur[1] - e.dy / (6 * scale)]; // 6 is an arbitrary constant to reduce rotation speed
      });
    }

My code works perfectly as expected, and comfortably performant normally.

But, when I zoom in all the way (so scale is now set to 8, and subsequently projection.scale is multiplied by 8), rotations and zooms become extremely laggy. Oddly, this lag is only noticed on Firefox. I tested on Chrome and Edge and they both are very performant.

After using the profiler in both Firefox and Chrome, there is some odd behavior in the call stack that I think is what is causing the perceived lag.

Chrome profiler on the left, Firefox profiler on the right.

The image shows the first four function calls in the profilers when dragging on my projection (which, again, calls my setRotation function, which changes the projection.rotate()). As you can see, the Firefox profiler shows massive delays between each function call, around 50ms for each of them. This continues the entire profiler (you can see that in the full range above). Interestingly, this doesn't happen in Chrome. You can see in the window to the right that there is no delay between each call, therefore, no lag.

This gap in calls is only present when scale is zoomed all the way in.

Firefox profiler when zoomed fully out, i.e. scale = 1

You can notice here that the function calls are without delay.

And as another example, Firefox profiler when zoomed about halfway in, i.e. scale ~= 4

You can see the function calls starting to get delayed, but not nearly as much as when fully zoomed in.

Is there some strange interaction between Firefox and d3 that I'm not accounting for?

Please let me know if you have any insight or where I should post this instead - thanks!

I've tried the same page on multiple computers and different browsers, and only Firefox produces this behavior.

0

There are 0 best solutions below