jgraph / mxgraph

mxGraph is a fully client side JavaScript diagramming library
Other
6.82k stars 2.06k forks source link

Performance on loading \ inserting \ zooming in mxgraph #265

Closed Blucbo closed 4 years ago

Blucbo commented 6 years ago

Currently I try to work with pretty big amount of objects in mxgraph, like rendering 10000 shapes at once. In that case there lots of problems with rendering cells. Each cell updated in a sequence, which leads to hanging browser. It would be great to use something like Cork / Uncork in nodejs. I will call something like mxgraph.stopUpdate(), add lots of elements, loadXML etc. and mxgraph.resumeUpdate() after finishing massive changes. Unfortunately I can't find methods to control update behavior in mxgraph in documentation.

Blucbo commented 6 years ago

There is an example of performance view in chrome image mxCellRenderer.redraw called multiple times, which could be avoided using proposed method before calling zoomin method.

IvanProdaiko94 commented 6 years ago

Hm, I suppose you could use requestIdleCallback as a fast solution

nosovk commented 6 years ago

@ivanProdaiko94 - probably it wouldn't help. The main question is how to avoid unnecessary Rendering, not how to make it less interruptive.

hildr commented 6 years ago

Probably there is also the same problem at draw.io - when I try to create lots of elements zoom starts to work very slow.

theUm commented 6 years ago

Hmm, looks like there is a solution in Java version, but not in JS

MaksymBulich commented 6 years ago

Probably setting display:none on svg will help a bit. You can hide svg, then re-render, then show it. But if it sucks in js - then it will not help.

nosovk commented 6 years ago

@Blucbo were you able to find any solution to improve performance?

Diaskhan commented 6 years ago

@nosovk U're using wrong Tool! Msxgraph purpose is to draw diagrams, not to draw 10000 objects!

Try to use d3.js maybe d3.js is capable !

  1. http://bl.ocks.org/robschmuecker/7926762
  2. https://bl.ocks.org/emeeks/306e64e0d687a4374bcd
  3. https://www.quora.com/Does-D3-js-work-efficiently-on-massive-amounts-of-data-200-million-rows-with-at-least-a-dozen-columns

Could U describe Use case of using huge amount of objects?

Blucbo commented 6 years ago

@Diaskhan I am developing graphic editor(area grid with squares). Mxgraph provide a lot of ready-made solutions therefore I chose this lib.

Slow method is redrawLabel slow-method

@nosovk I rewrote some methods and added hiding svg. It enhanced productivity execution, pictures below. before 10000standart after 10000optim

profit from 1.8 min -> to 3sec

But I have maximum 1000x1000 small squares that do crash :( Can somebody prompt me? (I have not time use other library, maybe create custom canvas render)

Diaskhan commented 6 years ago

Could u provide code to reproduce crashing ? And very interesting how much memory use 10 k objects!

Blucbo commented 6 years ago

Could u provide code to reproduce crashing ? And very interesting how much memory use 10 k objects!

https://codepen.io/bohdan-skochko/pen/aRgXPM?editors=1000

Diaskhan commented 6 years ago

What do U mean by saying Crashing ?

Blucbo commented 6 years ago

What do U mean by saying Crashing ? Set rowCounts = 1000, colCounts = 1000;|

tab browser dead

Diaskhan commented 6 years ago

Last chrome 64 bit! Normal fly!

Please provide information about os and broeser used! And ram of hardware ?

Blucbo commented 6 years ago

Last chrome 64 bit! Normal fly!

Please provide information about os and broeser used! And ram of hardware ?

Did you click on plus(for zoom)?

The question is how to speed up the process. User can use different devices and browsers.

Diaskhan commented 6 years ago

Yes. I clicked. Try demo on another browser or device!

Clear the cache !

Blucbo commented 6 years ago

Yes. I clicked. Try demo on another browser or device!

How long does it take to render after zoom? If you have ideas for improve performance say please.

Diaskhan commented 6 years ago

Слушай говорю же. ты используешь не тот инструмент ! Попробуй поискать что-нить другое для своих квадратиков !

Это библиотека для диграмм а не для рисования !

Blucbo commented 6 years ago

Слушай говорю же. ты используешь не тот инструмент ! Попробуй поискать что-нить другое для своих квадратиков !

Это библиотека для диграмм а не для рисования !

Well, I agree. But mxgraph solves the problem because there are many ready-made tools. Now my project have begun to expand to huge sizes. I improved the performance myself. Nobody will rewrite the finished part. Therefore, the answer to take another library does not fit. I would not write issue then.

The question of performance! How can I yet improve?(I thought maintainer will answer me, but no)

lijunay commented 5 years ago

In my drawings, there will be more than 2000 graphics, but by tracking the source code, it is very slow to find when scaling.

Each zoom is a modification of the value in the svg element, resulting in slower. Called after performing scaling mxGraphView.prototype.revalidate function this is my test drawing,has 2000 umlactor image It took more than 5 seconds to run to the validate function. How can I speed up? image

Blucbo commented 5 years ago

@lijunay In my case i draw only square or img without text label. As what you saw my photos above redraw label take longer time. I deleted call method redraw Label. Additional a hide svg element before zooming. In your case, you use a label in the element. You can only use toggle display svg. In additiong, I have a problem with memory. I create 200x200 grid with items and tab consumes 1GB memory. And after remove and clean graph memory do not clean. :( I think its because of a lot of recursive calls. How do we fix it?

Unfortunately, maintainers lib didn`t answer an issue :(

davidjgraph commented 5 years ago

We're starting a research task into using hardware zoom, rather than calculating the zoom internally and redrawing. It should address the main problems in this thread, but it's a minumum of 6-12 months work.

RolkerMan commented 4 years ago

We're starting a research task into using hardware zoom, rather than calculating the zoom internally and redrawing. It should address the main problems in this thread, but it's a minumum of 6-12 months work.

@davedwards Hi, I currently encounter the same problem mentioned in this thread. As for the main problems in this thread,maybe it's not just about zooming. In case of rendering big amount of objects in mxgraph,there is also an performance issue while loading/inserting/moving objects. Could you kindly explain whether the solution you are working on will solve these problems or not? And it would be nice to know about the progress of the research task. Thanks :)

RolkerMan commented 4 years ago

@Blucbo Hello,have you got performance issue while loading/dragging objects? Could you share some other workarounds(if there's any) for the problems? Thanks!

davidjgraph commented 4 years ago

The main issue here is manipulating a large SVG DOM takes time. The change for zooming involved SVG zoom, to avoid the SVG DOM API.

In terms of the other issues, the solutions are going to be application specific. But, as @Diaskhan points out, mxGraph isn't the right library if you looking to draw 10,000 shapes. You're better off with a WebGL or canvas based library that is written for high performance.

If you still pick mxGraph for a large diagram, you'll need to implement some application level of detail (LOD) functionality. That is, when a huge graph is zoomed out, rather than try to render everything, render some summary of groups of cells, instead.

The LOD example demonstrates showing different views based on zoom level. That said, I haven't checked whether this would actually solve performance issues at scale. It might be that you would need to create a "shadow model" of cells removed from the graph and add/remove depending on the viewpoint and zoom to keep the number of cells to a certain limit.

But, at point this I consider the issue closed. We've made improvements to the zoom. If the performance problems are elsewhere, I'd suggest a different library or some level of detail implementation.

You're still welcome to post additional issues on performance, but please make them very specific to certain operations, show the example you used to test and the results of your performance profiling.

Blucbo commented 4 years ago

@RolkerMan

I make 2 steps

  1. Set SVG display none before zooming
  2. I draw the only cells. I delete methods redrawLabel and redrawControl
mx.mxCellRenderer.prototype.redraw = function (state, force, rendering) {
    const shapeChanged = this.redrawShape(state, force, rendering);
    if (state.shape != null && (rendering == null || rendering)) {
      // this.redrawLabel(state, shapeChanged);
      this.redrawCellOverlays(state, shapeChanged);
      // this.redrawControl(state, shapeChanged);
    }
  };

@davidjgraph Thank you for your answer anyway

davidjgraph commented 4 years ago

I assume commenting out redrawLabel makes the main difference in terms of performance improvement

Blucbo commented 4 years ago

Yes, as we can see it on the picture above https://github.com/jgraph/mxgraph/issues/265#issuecomment-434691285

tianchao1995 commented 4 years ago

@Blucbo How did you finally work it out