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

xAxis.labels.useHtml suffers major performance hit with useHtml as true #7656

Closed
jmeyerit opened this Issue Jan 11, 2018 · 7 comments

Comments

Projects
None yet
3 participants
@jmeyerit

jmeyerit commented Jan 11, 2018

Expected behaviour

Similar rendering performance using html rendering options versus svg.

Actual behaviour

Suffer a large performance hit when rendering with xAxis labels using html rendering.

Use Case:

Client wants to view customer order data (includes tons hauled information and sale type) for the entire year. This is in bar chart form and can easily surpass 3000 rows. In addition, each row would have information on click/hover of the label in table format if necessary. Since svg doesn't have table rendering, we require useHtml for those labels without rewriting the logic for our hover data.

Live demo with steps to reproduce

The attached fiddle showcases the issue.

https://jsfiddle.net/cthchdfw/2/

After going to the fiddle, open your console and run the js file a few times. In my tests, rendering time took between 1.6-2.2 seconds. Now, change the htmlBool to true. Rendering times skyrocket to 9.4-10.0 seconds. This only gets worse as the dataset increases in size. If we change from the default 1000 to 3000 rows, we go from 9.1-10.3 seconds for normal svg render (which is, at least to our client, acceptable) vs 83-85 seconds for html render.

Using the Chrome profiler, I noticed a couple potential issues.

image

  1. HtmlUpdateTransform appears to be called multiple times inside and outside the Layout function.
  2. Recalculate Style is being called, taking 23% of the rendering time. I suspect that this may be the core of the issue. Using html rendering, the layout is constantly resizing (at least internally), and causing unnecessary updates.

Product version

highcharts >= 4.0.0 tested.

Affected browser(s)

Chrome only tested.

@pawelfus

This comment has been minimized.

Show comment
Hide comment
@pawelfus

pawelfus Jan 12, 2018

Contributor

Hi @jmeyerit

Thank you for reporting this performance issue.

For my machine it's ~1s for SVG and ~4s for HTML. Which is still ~4x slower for HTML.

Contributor

pawelfus commented Jan 12, 2018

Hi @jmeyerit

Thank you for reporting this performance issue.

For my machine it's ~1s for SVG and ~4s for HTML. Which is still ~4x slower for HTML.

@pawelfus pawelfus added the Bug label Jan 12, 2018

@TorsteinHonsi

This comment has been minimized.

Show comment
Hide comment
@TorsteinHonsi

TorsteinHonsi Jan 12, 2018

Collaborator

On my machine, in Chrome, it rendered in ~2500ms before the fix.

After the fix, it renders in ~270 ms: https://jsfiddle.net/highcharts/cthchdfw/5/

The fix does mainly two things:

  • Avoid applying changes unless necessary. For example, the SVGRenderer's model of deferring element update until all attributes of an .attr() call are set, is now also applied to HTML elements.
  • Avoid refering to elem.offsetWidth. This caused recalculating style as noted in the OP, and chopped off the last 300ms.
Collaborator

TorsteinHonsi commented Jan 12, 2018

On my machine, in Chrome, it rendered in ~2500ms before the fix.

After the fix, it renders in ~270 ms: https://jsfiddle.net/highcharts/cthchdfw/5/

The fix does mainly two things:

  • Avoid applying changes unless necessary. For example, the SVGRenderer's model of deferring element update until all attributes of an .attr() call are set, is now also applied to HTML elements.
  • Avoid refering to elem.offsetWidth. This caused recalculating style as noted in the OP, and chopped off the last 300ms.
@jmeyerit

This comment has been minimized.

Show comment
Hide comment
@jmeyerit

jmeyerit Jan 12, 2018

Wow, thanks for the quick reply and fix. Interesting enough, I'm now seeing worse performance using svg. The fix swapped the performance bottleneck around making html rendering faster, at least in this case. In my recent test of 1000 rows using the updated fiddle, I get ~500ms render time using html labels and ~1500ms render time for svg.

In my own testing environment, I'm seeing about a 2x decrease in rendering speed overall. Perhaps more can be optimized in my environment if using html over svg rendering translates to faster rendering for other types of elements. Needless to say, this is incredibly exciting. Thanks again for looking into this issue.

jmeyerit commented Jan 12, 2018

Wow, thanks for the quick reply and fix. Interesting enough, I'm now seeing worse performance using svg. The fix swapped the performance bottleneck around making html rendering faster, at least in this case. In my recent test of 1000 rows using the updated fiddle, I get ~500ms render time using html labels and ~1500ms render time for svg.

In my own testing environment, I'm seeing about a 2x decrease in rendering speed overall. Perhaps more can be optimized in my environment if using html over svg rendering translates to faster rendering for other types of elements. Needless to say, this is incredibly exciting. Thanks again for looking into this issue.

@TorsteinHonsi

This comment has been minimized.

Show comment
Hide comment
@TorsteinHonsi

TorsteinHonsi Jan 22, 2018

Collaborator

Thanks, I have a few ideas of how to increase rendering speed significantly in SVG too.

Before I dive in, are you sure the performance decreased when using SVG, compared to earlier? I can't see any difference in rendering speed before and after, and it doesn't make sense either, since the only change in non-HTML related code was to move some variables around.

@pawelfus did you experience this?

Collaborator

TorsteinHonsi commented Jan 22, 2018

Thanks, I have a few ideas of how to increase rendering speed significantly in SVG too.

Before I dive in, are you sure the performance decreased when using SVG, compared to earlier? I can't see any difference in rendering speed before and after, and it doesn't make sense either, since the only change in non-HTML related code was to move some variables around.

@pawelfus did you experience this?

@jmeyerit

This comment has been minimized.

Show comment
Hide comment
@jmeyerit

jmeyerit Jan 23, 2018

I am sorry, I was incredibly ambiguous in my wording choice. What I meant to say was, since the performance improvement you made, html is now faster at rendering than svg. The svg rendering time is still the same and was not affected.

jmeyerit commented Jan 23, 2018

I am sorry, I was incredibly ambiguous in my wording choice. What I meant to say was, since the performance improvement you made, html is now faster at rendering than svg. The svg rendering time is still the same and was not affected.

@TorsteinHonsi

This comment has been minimized.

Show comment
Hide comment
@TorsteinHonsi

TorsteinHonsi Jan 25, 2018

Collaborator

That makes sense, thanks!

Collaborator

TorsteinHonsi commented Jan 25, 2018

That makes sense, thanks!

@TorsteinHonsi

This comment has been minimized.

Show comment
Hide comment
@TorsteinHonsi

TorsteinHonsi Jan 25, 2018

Collaborator

The above commit reduces rendering times with SVG labels from ~700ms to ~350ms on my system. It checks for the length of each label before setting the width pseudo-CSS, thereby avoiding the heavier word-wrap logic.

Collaborator

TorsteinHonsi commented Jan 25, 2018

The above commit reduces rendering times with SVG labels from ~700ms to ~350ms on my system. It checks for the length of each label before setting the width pseudo-CSS, thereby avoiding the heavier word-wrap logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment