Skip to content

Fix scattergl plot freezing up on hover - #8052

Open
emilykl wants to merge 3 commits into
plotly:mainfrom
emilykl:fix-slow-scattergl-hover-emilykl
Open

emilykl wants to merge 3 commits into
plotly:mainfrom
emilykl:fix-slow-scattergl-hover-emilykl

Conversation

@emilykl

@emilykl emilykl commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Closes #5927
Closes #5790
Closes #8036

(Supersedes #7998)

Fix unreasonably slow scattergl hover behavior (to the point of freezing) in the default case. Even with this fix, the hover is still somewhat laggy, but doesn't freeze entirely as in the linked issues.

The scattergl hover logic was following a code path which looks for nearby points to draw spikelines to. This code path was being followed even when spikelines were not enabled. The search is very slow with large numbers of points. This PR adds a guard to skip the "find nearby points" search unless required.

Note: For the diff chunk in src/components/fx/hover.js starting on line 671, the only meaningful change is adding canSpikeToNonHoveredPoint() to the if condition. The rest of that diff is just indentation change from collapsing two nested if statements into 1.

Screen recording

This video shows the performance I see on my machine after this fix, with extremely closely-spaced points.

scattergl-hover.mov

Steps for testing:

  1. Use the code snippet provided in #8036:
    const n = 100000;
    
    Plotly.newPlot('graph', [{
      type: 'scattergl',
      mode: 'markers',
      x0: 0,
      dx: 1,
      y: Array(n).fill(0)
    }]);
  2. Paste into devtools dashboard on this branch
  3. Hover over individual points. Notice that the hover is more-or-less functional, although it may be a bit laggy.
  4. Run the same code snippet in the devtools dashboard on main. Notice that the entire plot freezes completely when trying to hover.

Caveat

There's an underlying performance issue which is not addressed by this PR, which probably deserves its own issue. #8036 points out that there's a performance cliff which starts at 100k points, even though 99,999 points are fine. At 100k points we exceed the TOO_MANY_POINTS constant defined in src/traces/scattergl/constants.ts, which triggers us to use a tree data structure for searching through points, rather than a plain array.

I haven't fully investigated but there seems to be some performance issues with that tree implementation (which is ours: see https://github.com/plotly/point-cluster), specifically with the .range() function called here. It's extremely slow when given infinite bounds, and seems to be slower than regular array traversal whenever the bounds cover a significant fraction of the total points. Either we're calling the .range() function in a non-optimal way, or there's a bug in the implementation. Hence why even with this fix, the scattergl hover is still somewhat laggy as soon as we exceed 100k points.

@emilykl emilykl changed the title Fix slow scattergl hover Improve scattergl performance on hover Sep 17, 2026
@emilykl emilykl changed the title Improve scattergl performance on hover Fix scattergl plot freezing up on hover Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant