-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Fix: Optimize Drawing.bBox calls to prevent unnecessary reflows in complex DOMs #7497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: Optimize Drawing.bBox calls to prevent unnecessary reflows in complex DOMs #7497
Conversation
Thanks @imbansalaniket! There are two cases I'd be concerned about here, which are the original reasons we created Drawing.bBox
in the first place:
- the
<div>
we're plotting into isn't part of the DOM yet. - the
<div>
or its parents have CSS transforms applied.
I suspect that when we originally wrote this getBBox
didn't have sufficient support or gave browser-dependent output, but it looks like at least the support has been good for years now. And perhaps its distinct characteristics vs getBoundingClientRect
mean we don't need to worry about CSS transforms anymore?
Anyway if we can ensure these cases still work, and fix the various test failures (there are a bunch of image tests that fail, you can see them in the artifacts here: https://app.circleci.com/pipelines/github/plotly/plotly.js/12418/workflows/12a27ec0-ea1e-45f9-9d25-196d14e5e1b7/jobs/275741/artifacts - also looks like one jasmine test failed here: https://app.circleci.com/pipelines/github/plotly/plotly.js/12418/workflows/12a27ec0-ea1e-45f9-9d25-196d14e5e1b7/jobs/275729) then I'm all in favor of this change.
I guess the other thing to say is we really shouldn't need to do this at all for non-text nodes. I know there are a few cases where we currently do call Drawing.bBox
on non-text nodes but in principle we can directly calculate what we need for these cases, which will always be better than asking the browser.
Hi @alexcjohnson, thanks for your feedback,
1. the <div> we're plotting into isn't part of the DOM yet.
- yes this make sense as getBBox
return empty object for the node which are not in the DOM, for such node we still need to rely on getBoundingClientRect
.
2. the <div> or its parents have CSS transforms applied.
- as you mentioned, yes, getBBox is independent from any transform applied on the node.
For the failing test and recommendation point 1. the <div> we're plotting into isn't part of the DOM yet.
, I will add a fix in upcoming commit.
Thanks
Hi,
any update on this PR?
Thanks
Description
This PR addresses a performance issue caused by repeated calls to
Drawing.bBox
which appends and remove test node to the tester element in the DOM, which were leading to unnecessary layout reflows—especially in scenarios involving complex DOM structures or a large number of CSS variables. These frequent reflows resulted in noticeable performance degradation during initial chart rendering and interactions like resizing, panning, zooming, or updating plots.Background
calls were forcing synchronous reflows in
Drawing.bBox`.Changes Introduced
Width/height optimization:
getBBox()
when only size metrics are needed (avoiding full Drawing.bBox).Drawing.bBox logic
getBBox
fails to compute position fortext
node correctly. Raised here )Impact