Closed GoogleCodeExporter closed 8 years ago
I'm always interested in ways to make the drawing faster. as it happens i was
doing some changes to the state machine connector yesterday and it occurred to
me that the bezier calculations are a whole other area where i could implement
caching; i think it would save a lot of thrashing around. so this issue is
timely.
what would be awesome is if i could somehow recreate this exact setup. would
it be possible for you to create a test page of this somehow? you could always
contact me via email if your stuff needs to be private.
Original comment by simon.po...@gmail.com
on 22 Jun 2012 at 10:04
btw i have a load test page which draws 1520 connections in 2.8 seconds on
Chrome - significantly more than what your diagram shows. so i will need to get
a page from you that replicates the issue or i won't be able to debug what's
going on.
Original comment by simon.po...@gmail.com
on 23 Jun 2012 at 8:12
Hi,
Sure ill extract the code to amke a standalone example. Ill post a link here
when its ready.
Original comment by mfc...@gmail.com
on 23 Jun 2012 at 10:12
great, thanks.
Original comment by simon.po...@gmail.com
on 23 Jun 2012 at 9:37
Hi again,
So here is my very basic test case: http://jsfiddle.net/XVFwa/.
The blocking doesn't seem so evident in chrome. Firefox does block for 2-3sec.
I have included a loading gif to show that the browser actually blocks while
loading.
Not sure why jsPlumb has decided to ignore my stroke styles in my test.
The JSON has lots of stuff that is not relevant to the test. Ill clean it up
once i have more free time.
Original comment by mfc...@gmail.com
on 25 Jun 2012 at 9:30
I forgot to include in the issue that closing my editor with the calls:
jsPlumb.reset(); and container.empty(); is also slow.
If i remove the reset() call it becomes instantaneous. Pretty sure that without
reset stuff will remain and when i instantiate a new editor im going to have
problems.
Original comment by mfc...@gmail.com
on 25 Jun 2012 at 10:14
thanks for that page. i have been writing a little load test harness page in
development; you can see it here:
http://morrisonpitt.com/jsPlumbTest/tests/loadTestHarness.html
click 'Run Test' and it goes pretty quickly. but click it again and it takes a
long time, and then you'll see the timing for the reset - for me on Chrome on
Mac it takes about 13.5 seconds.
It's a bit of a bummer that ".empty" is slow. because i was thinking of
changing jsPlumb.reset to use that (at the moment it loops through all the
connections). and at that point we are getting down to the browser level,
beyond which i can't do anything to make things quicker. well, at least i
*think* we're getting down to the browser level. maybe .empty jumps through a
lot of hoops that i could avoid by going straight to the DOM.
Original comment by simon.po...@gmail.com
on 25 Jun 2012 at 10:26
I might not have explained correctly. Its reset that is slow, not empty.
Using just empty its fast =).
Original comment by mfc...@gmail.com
on 25 Jun 2012 at 10:30
Interesting ... Removing jsPlumb.setSuspendDrawing(true) has no effect on my
case.
Yet on your test if I remove setSuspendDrawing it crashes chrome =).
Original comment by mfc...@gmail.com
on 25 Jun 2012 at 10:34
re comment 8: ok cool. that's good. so i will probably not actually use
.empty; i'll use straight up DOM removes. but it's good to know that that will
be quick enough.
re comment 9: do you mean that in the code that generates the diagram above,
setSuspendDrawing makes no appreciable difference to the speed at which the UI
is drawn? It's slow either way?
my test page is designed to do an excessive amount of drawing; i intend to use
it to tune up jsPlumb's performance to the point where hundreds of connections
are possible. within browser constraints, of course. are you on Windows?
Original comment by simon.po...@gmail.com
on 25 Jun 2012 at 10:42
I'm on OSX. The problem is also present on Windows 7.
I'm running the profiler trying to figure out what I'm doing that might cause
the problem.
Suspects so far:
- The code in "jsPlumb.Overlays.Label.setLabel" doesn't seem to check if it should repaint or not. Might be present on another function.
- The calls to jquery ui draggables seem to take up a bit of time. Guessing there is no way around this.
- jsPlumb.CurrentLibrary.getSize gets called in a few places. I might try to cache its values for loading the initial connections.
The quest continues =).
Original comment by mfc...@gmail.com
on 25 Jun 2012 at 11:13
interesting about the setLabel thing - i will take a look at that in dev. it
would explain why setSuspendDrawing has no effect for you.
the calls to .draggable, yeah, might be unavoidable. well, nothing's
unavoidable, of course, but maybe the payoff for re-engineering that would be
low.
i'm not sure that the getSize calls would be slowing things down a great deal.
i think the label issue you identified would have much more of an effect.
Original comment by simon.po...@gmail.com
on 25 Jun 2012 at 11:21
Last observations for today:
- Removing the label does provide a slight speed bump.
- When using self referencing connections there is a lost empty div that should contain the endpoint (an svg in chrome). This div contains "ui-draggable". Maybe it is being processed by jquery ui when in fact it serves no point when its empty.
I will keep on looking for a way to make it smoother to load =).
Original comment by mfc...@gmail.com
on 25 Jun 2012 at 11:41
i just made some updates in dev (not on the test site yet) - adding a check to
the setLabel function to not paint if drawing is suspended does have quite a
good effect. i was getting 700ms to do the full paint with no setLabel call,
and 4500ms with a setLabel call on each connection. adding the code to honour
'suspendDrawing' took that number down to 2700ms with a setLabel call.
it's still not fast enough though. i'll keep looking.
Original comment by simon.po...@gmail.com
on 26 Jun 2012 at 12:54
i have a similar problem but i think the repaintEverything after painting has
been unsuspended is a bit slow. i have 110 endpoints and 71 connections and
repaint takes around 4 seconds to repaint everything. in chrome timeline it is
doing lots of relayout events (~252) that take ~18ms each. it looks like i get
one for each endpoint and 2 for each connection (one for label and one for
connection itself i think). i suspect it might be possible to improve this if
the calculation of all the positions is done in one step and then changing all
the styles is done in another step.
i also have problem prior to repaintEverything because of
labels/droppable/draggable.
i have a fiddle which shows the general problem:
http://jsfiddle.net/kvWBG/
the performance of the layout ends up being quadratic to the number of elements
:(
http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/
Original comment by benmmur...@gmail.com
on 4 Jul 2012 at 10:11
i have found the reason for the reset being slow. on a branch in dev this is
fixed - 40 seconds for one particular reset became 34 milliseconds.
Original comment by simon.po...@gmail.com
on 8 Jul 2012 at 7:04
Cool ty. Ill give it a try ASAP =).
Original comment by mfc...@gmail.com
on 9 Jul 2012 at 2:53
i havent checked this in yet. will let you know once i have.
Original comment by simon.po...@gmail.com
on 10 Jul 2012 at 12:33
this is checked in now.
Original comment by simon.po...@gmail.com
on 17 Jul 2012 at 8:53
[deleted comment]
Ok i have included all the files like in the tests and i get: "undefined is not
a function" 49 times at line 4289 in jsPlumb-1.4.0-RC1.js
Not sure if im missing something.
Original comment by mfc...@gmail.com
on 17 Jul 2012 at 9:58
Ok Got it. Was missing the state-machine.js
Unfortunately the performance didn't change much.
It is a little better. With my hack to delay connection rendering neither
firefox nor chrome block the browser anymore.
Original comment by mfc...@gmail.com
on 17 Jul 2012 at 10:11
the performance of reset now is significantly faster than it was before. what
are you referring to when you say the performance didn't change much?
Original comment by simon.po...@gmail.com
on 17 Jul 2012 at 10:16
Its the performance of loading the connections on startup.
I realize that there are some other factors that seem make it worst in my case.
In the fiddle (http://jsfiddle.net/XVFwa/) the loading only blocks for a split
second. In my app it blocks for 3-5 sec atm.
I will keep looking for the guilty code =). If you want you can close the
ticket.
The reset is indeed faster.
Original comment by mfc...@gmail.com
on 17 Jul 2012 at 10:30
Maybe closing is not the best solution.
There is another person that is reporting a similar problem (Comment 15 by
benmmur).
Original comment by mfc...@gmail.com
on 17 Jul 2012 at 10:33
yeah it's reset i was talking about. this issue has morphed into two separate
issues.
you mentioned a hack you have written to delay connection rendering. how are
you doing that?
Original comment by simon.po...@gmail.com
on 17 Jul 2012 at 10:46
oh is that the loop thing you talked about in your first comment.
Original comment by simon.po...@gmail.com
on 17 Jul 2012 at 11:05
I run through my connections and schedule the creation with jquery timers:
$(self).oneTime((k * 20), function() {
// create the connection
});
This spreads the creation into 20ms intervals and avoids browser blocking.
Firefox still chockes a little.
With this hack jsPlumb.setSuspendDrawing(true); becomes irrelevant.
The downside is that the user sees the graph being drawn. It is actually funny
to see it draw live =).
Original comment by mfc...@gmail.com
on 17 Jul 2012 at 11:09
yeah i quite like the idea of seeing it drawn live actually ;)
i just updated the test site, so this is the load test page with what is
currently in dev:
http://morrisonpitt.com/jsPlumbTest/tests/loadTestHarness.html
i saw the other guy's comment about repainting. strangely, though, i don't see
that many layout events when i watch the load test page in chrome timeline.
Original comment by simon.po...@gmail.com
on 17 Jul 2012 at 11:12
Another test i have done is use jsPlumb.setSuspendDrawing(true) and
jsPlumb.setSuspendDrawing(false, true) in the last connection. It takes 20ms x
connections to create but renders instantly.
This does point to the problem not being the actual render but maybe the math
for creating the connections with the labels?
Original comment by mfc...@gmail.com
on 17 Jul 2012 at 11:15
have you looked at the load test page? you can try various combinations and
you will see that labels do indeed slow things down.
Original comment by simon.po...@gmail.com
on 17 Jul 2012 at 11:17
Yeah the behavior im seeing is similar to the one in the test. My browser
blocks for 2-3secs in the test.
I see the reset has really improve congrats =).
Original comment by mfc...@gmail.com
on 17 Jul 2012 at 11:18
ah, well, good to know that we have a solid test case for what someone is
experiencing out there in the real world...improving the performance of this
page should, in theory, improve performance for everyone.
if you look at the breakdown of timings on that page you see that the 'repaint'
time (all the drawing) is always a bit more than the 'create' time (all the
maths...but includes the addition of elements to the DOM). in FF with 10
elements I get a create time of 1010ms and a repaint time of 2082ms. the
average create time is ~ 2.3ms. changing the number of elements has a small
effect on the average create time but it is repaint that starts to blow out.
so it is there that i will concentrate first.
reset is indeed a lot better now. i am considering actually releasing 1.3.11
instead of 1.4.0, with the reset fix in it (plus a couple of other things),
because i know a few people are waiting for it.
Original comment by simon.po...@gmail.com
on 17 Jul 2012 at 11:29
[deleted comment]
[deleted comment]
redo from start
Original comment by simon.po...@gmail.com
on 25 Jul 2012 at 10:11
i have split out two issues from this:
issue 267 - setLabel ignores suspendDrawing flag
issue 268 - deleteEveryEndpoint should suspend drawing
this issue is now a general issue about how people would like jsPlumb to draw
faster.
Original comment by simon.po...@gmail.com
on 25 Jul 2012 at 10:37
Original comment by simon.po...@gmail.com
on 26 Jul 2012 at 12:02
i just pushed a change to 1.3.12 dev that provides a further performance
enhancement when using labels - jsPlumb now caches the dimensions of a label
once it has been calculated. Prior to this change, it was going off to
calculate the dimensions each time a paint was performed (it needs to do this
in order to be able to create a parent container large enough to hold the
label).
so as i said, as of 1.3.12 the label's dimensions are cached. the cache is
cleared if you change the label's text, of course, and there is another method
that forces a cache clear (in case you made a change via CSS, for example).
For the default case in the load test page, result comparison is:
Before
-----
Total time: 2156
Create time: 526
Average create time: 1.2944444444444445
Repaint time: 1630
After
----
Total time: 1540
Create time: 531
Average create time: 1.3555555555555556
Repaint time: 1009
...so it's now about 30% faster (this is with labels of course. without labels
the performance is unchanged).
Original comment by simon.po...@gmail.com
on 12 Aug 2012 at 3:38
[deleted comment]
[deleted comment]
[deleted comment]
[deleted comment]
Just pushed a change into 1.3.13 development which sees a further performance
gain.
1.3.12
-----
Total time: 1581
Create time: 601
Average create time: 1.4777777777777779
Repaint time: 980
1.3.13
------
Total time: 1121
Create time: 164
Average create time: 0.33055555555555555
Repaint time: 957
this change affects all connections - those with labels and those without. it
involved reducing the number of calls to get the offset/size of elements during
the time that drawing is suspended (you can see this reflected in the fact that
'create' time is much quicker but repaint time is pretty much unchanged).
Original comment by simon.po...@gmail.com
on 27 Aug 2012 at 1:18
Original comment by simon.po...@gmail.com
on 27 Aug 2012 at 1:18
Hi there,
I have tested 1.3.13 and the performance is amazing =). Congratz !!
Just trying to decide if i leave the loading part for the cool effect =P.
Loading is now 1s or less =). Amazing job =).
Original comment by mfc...@gmail.com
on 5 Sep 2012 at 1:31
awesome!
thanks for the update - i appreciate the feedback.
Original comment by simon.po...@gmail.com
on 5 Sep 2012 at 9:57
closing.
Original comment by simon.po...@gmail.com
on 30 Apr 2013 at 11:33
how was this solved exactly? cuz i just ran into the same problem and i have
around 150 connections only :S...but the operation is taking >50s !!!
Please help :( i know its fixed but i need to know..kinda got confused with all
the posts
Original comment by Mero.R...@gmail.com
on 3 May 2013 at 2:39
Hi,
I am facing the same issue. For 386 connectors its taking 15.107 sec and for
445 connections its taking 24.961 sec.
The setSuspendDrawing method has no affect on execution time. I am using
version 1.3.13. Its flowchart based and endpoints are dots.
Please help.
Original comment by jayant...@gmail.com
on 18 Sep 2013 at 4:45
Original issue reported on code.google.com by
mfc...@gmail.com
on 22 Jun 2012 at 5:34Attachments: