Letractively / svgweb

Automatically exported from code.google.com/p/svgweb
Other
0 stars 0 forks source link

Reduce the number of Sprites created per Node to increase performance #315

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Currently roughly four Sprites are created for every SVG node. Performance
testing has found that the speed of panning and zooming an entire SVG
image, such as the Wikipedia prototype in Issue 291 or Michael Neutze's
German Atlas at http://vis.uell.net/gsvg/electionAtlasGermany.html are very
sensitive to the number of Sprites. Dragging the SVG image in these
scenarios is currently quite sluggish as compared to native speeds. In
fact, this is the primary bottleneck in the dragging scenario. I haven't
proved it, but I suspect that this might be the primary current bottleneck
with Flash performance in general.

To show that this was the bottleneck, I started with the Tux.svg file from
Wikipedia at http://commons.wikimedia.org/wiki/File:Tux.svg . I did a test
to see if the number of Sprites affected performance. I created a reduced
test case where I made about 7500 Sprites on the screen that each drew a
circle. I then attached a mouse move listener to the Stage to change the
top-level transform.matrix based on where the mouse was. The 7500 number
came from counting the number of nodes in the Tux.svg sample file I've been
using (which is about 1915 nodes) and then multiplying by 4 to simulate
making 4 Sprites per node, coming to about 7660. The performance looked and
felt similar to what I was experiencing earlier, which is a sluggish
response time as I moved the mouse around. I then experimented with
simulating only having one Sprite per node (i.e. 1915 sprites) and the
performance was much faster.

This leads me to believe that the number of Sprites per node is definitely
having an affect on performance, at least when it comes to panning the
top-level container element.

As an optimization, I tried having 7500 Shapes instead of Sprites, but the
affect on performance was hard to tell and it obviously didn't give enough
to matter.

Further tests:

* making wmode on the Flash object be transparent or opaque has no big
affect on performance
* setting quality to low or medium makes things a bit faster but not worth
the quality degradation
* getting rid of preserving XML whitespace behavior (i.e. turning the
whitespace into nodes) reduces the node count on my sample SVG file from
1915 nodes to 901 nodes, a significant reduction. This should have a very
large corresponding affect on performance since each node become a large
number of Sprites. I think it's worthwhile to explore removing XML
whitespace compatiblity for SVG OBJECTs for the performance payoff
(http://code.google.com/p/svgweb/issues/detail?id=310).

The two big take aways:
* We really need to reduce the number of Sprites per node as close to 1 as
possible
* We should probably remove XML whitespace compatibility (i.e. whitespace
nodes show up in the DOM) - tracked by Issue 310 that I will take on

I have attached the testing files to this bug that focus just on Flash to
remove JavaScript from the performance situation:
* TestMe.as - Main ActionScript testing class that creates thousands of
TestMeCircle.as classes which are Sprites. We set the number of
TestMeCircles to create to simulate the number of Sprites per SVG Node.
* TestMeCircle.as - ActionScript class that extends Sprite.
* testme.html - Container file to show TestMe.swf
* TestMe.swf - Built testing file

These files can be used to test the raw Flash performance of Sprites. I
compiled them as follows:

mxmlc TestMe.as -compiler.strict=true -compiler.optimize=true
-compiler.debug=false

In the loop in TestMe.as you can change the number of Sprites to simulate
the Tux.svg file in different scenarios:

* 901 TestMeCircle Sprites created - Simulates throwing away whitespace to
reduce number of nodes and having only one Sprite per SVG Node
* 1915 TestMeCircle Sprites created - Treating whitespace as we do now but
having one Sprite per SVG Node
* 3830 TestMeCircle Sprites created - XML whitespace handling and 2 Sprites
per SVG Node
* 7660 TestMeCircle Sprites created - XML whitespace handling and current
scenario of 4 Sprites per SVG Node

As you can see, getting the number of nodes down by 1/2 or 1/4
significantly improves the performance of dragging; I suspect it aids
performance through everything on Flash as well, even better probably for
SVG Web since we not only have 4 Sprites per Node but these are nested, one
a child of the other, which creates very deep Sprite hierarchy chains that
I am sure affects performance even more.

I've also attached a reduced test case that removes much of the Wikipedia
chrome and delegates the actual dragging over to the Flash side so that
only Flash and not JS performance is being measured and tested. This can be
used to see any affects on performance as you tinker with the number of
Sprites on the Flash side. This includes some patches to add some testing
methods over to SVGSVGNode.as and SVGViewerWeb.as. The files:
* testpan.html - Run this to show the Tux.svg file. Once it is loaded just
run your mouse over the SVG OBJECT area to have Tux the friendly penguin
drag around. Notice that it is jerky with the current settings.
* Tux.svg - Testing SVG file
* SVGViewerWeb.as - Add testZoomAndPan and handleZoomAndPan methods for
testing.
* SVGSVGNode.as - Adds some small properties for debugging.

Original issue reported on code.google.com by bradneub...@gmail.com on 19 Sep 2009 at 11:57

Attachments:

GoogleCodeExporter commented 8 years ago
Notes from Rick via email on this issue:

Regarding the multiple Sprites issue, for reference, Issue 128 [1] is the issue 
where
this design trade off was last evaluated and documented.

Originally, the code was designed to consolidate the Sprites and the 4 sprites 
would
just be aliases for a single sprite. (A benefit of the massive effort to 
centralize
the design, which was Issue 64 [3] and r375 [4].)  The revision where we 
switched to
"always on" multiple sprites was r636 [2] . As you can see, the amount of code 
which
changed the design was minimal.

However, as Issue 128 describes, the problem with the consolidated sprite 
design is
that dynamic scripting can change the properties and introduce a quirk scenario 
and
then you do need to have multiple sprites and so you'd have to deal with those
scenarios on the fly. I was not too excited about the complexity and performance
issues of detecting those corner cases dynamically but that is what would need 
to be
done to make this design work. Its not a terrible situation. Its just 
complexity I'd
rather not have to deal with. The performance concern is that we would need to 
check
a few attributes for a quirk scenario on every relevant setAttribute call. I'm
hopeful, though, that the performance issues will not be significant.

If you think the performance benefits are worth it, though, I'm willing to work 
on
getting this functional again. Would you mind opening an Issue and assigning it 
to
me? If you could include the scenario where you see lag, that would be helpful. 
I
know its the pan and zoom stuff, but if you could say exactly which files and
sequence of operations I should play with to know if progress is made that 
would be
helpful. Also, if you could give some hints as to priority, that would be 
great, as I
am juggling a few things right now.

Thanks,
Rick

1. http://code.google.com/p/svgweb/issues/detail?id=128
2. http://code.google.com/p/svgweb/source/detail?r=636
3. http://code.google.com/p/svgweb/issues/detail?id=64
4. http://code.google.com/p/svgweb/source/detail?r=375

Original comment by bradneub...@gmail.com on 19 Sep 2009 at 11:57

GoogleCodeExporter commented 8 years ago
Started in r894:
Change SVGNode inheritance from Sprite to a non-display class to account for
non-display nodes such as SVGDOMTextNodes. Also, create extra sprites only when
certain features are used instead of creating them just in case (which is a 
reversal
of Issue 128 / r636). Certain quirks may reappear in scripting scenarios until
further works is done on this.

The % reduction in sprites was significant. See spreadsheet:

http://spreadsheets.google.com/pub?key=tflExO9S_Nsm8uIfFIbPfpg&output=html

In contrast with the provided test case, the extra sprites used in SVG Web are
generally not doing much so I was not sure that removing them would make a
significant difference. However, once the extra feature sprites and once all 
sprites
for DOMText nodes were removed, the performance improvement was noticeable 
which is
good news.

This was a significant design change affecting hundreds of lines of code. It 
may take
time to clean up loose ends (bugs).

Original comment by grick23@gmail.com on 26 Sep 2009 at 9:38

GoogleCodeExporter commented 8 years ago
There is still potential for sprite reduction, but the vast majority of savings 
has
already been had. This work is essentially completed and fallout seems to be 
minimal
so I am going to close this. Any further incremental improvements can be 
tracked as
separate issues.

Original comment by grick23@gmail.com on 11 Oct 2009 at 7:36