Last Comment Bug 598040 - Poor performance w. canvas-based library
: Poor performance w. canvas-based library
Status: RESOLVED FIXED
: perf
Product: Core
Classification: Components
Component: Graphics (show other bugs)
: Trunk
: x86 All
: -- normal (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
:
Mentors:
http://kangax.github.com/fabric.js/an...
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-09-20 08:49 PDT by Juriy "kangax" Zaytsev
Modified: 2011-10-07 18:21 PDT (History)
7 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments

Description Juriy "kangax" Zaytsev 2010-09-20 08:49:07 PDT
In this demo (http://kangax.github.com/fabric.js/test/benchmarks/animation.html), I get ~40 fps in latest Firefox (4.0b7pre on Mac OSX, released 9-20-2010) and 100+ fps in Opera 10.70 and IE9. The animation is also jerky in Firefox, but is smooth in IE and Opera.

The demo consists of a 600px-by-600px canvas, and some graphics (with overall complexity of ~4000 paths) being constantly redrawn on canvas.

I would love to know the reason for such low performance, and if anything can be done about it.

Thank you.
Comment 1 Boris Zbarsky [:bz] (Out June 25-July 6) 2010-09-20 09:44:03 PDT
> I get ~40 fps in latest Firefox (4.0b7pre on Mac OSX, released 9-20-2010) and
> 100+ fps in Opera 10.70 and IE9.

Are you running IE9 on Mac OSX?  If not, why not compare to a Windows Firefox build?

That said, I see us getting about 58fps on Mac compared to Opera 10.6 getting about 160.  But that could just be due to the drawImage work happening async in Opera... certainly the way the web page measures fps is pretty bogus.
Comment 2 Boris Zbarsky [:bz] (Out June 25-July 6) 2010-09-20 09:45:50 PDT
Specifically, the page measures fps by making a single drawImage call, timing how long it takes to return from it (in ms), and then dividing 1000 by that number.

So to be fast, you can either make the drawImage fast or make it async.
Comment 3 Juriy "kangax" Zaytsev 2010-09-20 09:50:15 PDT
I'll check FF nightly on Windows 7 now (where I tested IE9). I understand that Opera can just be performing some work asynchronously (which would explain higher FPS), but I still see jerkiness in FF, and none in Opera. Do you see this animation smoothness difference in Opera vs FF?
Comment 4 Boris Zbarsky [:bz] (Out June 25-July 6) 2010-09-20 09:55:53 PDT
I should note that on the same machine, a 64-bit Mac build is at 76fps instead of 58.  ;)

And I was wrong in comment 1 and 2; there's no drawImage involved, just path drawing on the canvas.  

A profile of the 64-bit build above shows that we spent 75% of our time under nsCanvasReneringContext2D::DrawPath, called from Fill().  This is almost entirely under CGContextDrawPath in CoreGraphics path-drawing code (aa_render self time is half of this path-drawing time, in fact).  Are we perhaps using different antialiasing settings from Opera?

The remaining 25% of the time is under BezierCurveTo, ClearRect, FillRect, actually running JS, etc.

Oh, and I see no difference in the smoothness; both have a slight deterministic jerk once per rotation that I assumed was just due to the web page code.
Comment 5 Juriy "kangax" Zaytsev 2010-09-22 15:42:44 PDT
(In reply to comment #4)
> I should note that on the same machine, a 64-bit Mac build is at 76fps instead
> of 58.  ;)

Nice. Good to know.

> 
> And I was wrong in comment 1 and 2; there's no drawImage involved, just path
> drawing on the canvas.  

Yep. Those shapes are represented with ~1000 paths each (no images).

> 
> A profile of the 64-bit build above shows that we spent 75% of our time under
> nsCanvasReneringContext2D::DrawPath, called from Fill().  This is almost
> entirely under CGContextDrawPath in CoreGraphics path-drawing code (aa_render
> self time is half of this path-drawing time, in fact).  Are we perhaps using
> different antialiasing settings from Opera?
> 
> The remaining 25% of the time is under BezierCurveTo, ClearRect, FillRect,
> actually running JS, etc.

Interesting, and thanks for looking into it!

`clearRect` is used to clear canvas on every frame rendering. The rest is drawing. There's an SVG shape (http://kangax.github.com/fabric.js/test/demo/assets/7.svg) that's being downloaded, parsed and is then represented on canvas as a plain JS object. That object knows how to render itself on canvas, and the way it's doing it is basically by calling bunch of `bezierCurveTo`, `quadraticCurveTo`, etc.

The animation loop merely changes object's properties (angle, in this case) and redraws the viewing area.

> 
> Oh, and I see no difference in the smoothness; both have a slight deterministic
> jerk once per rotation that I assumed was just due to the web page code.

I tried demo in IE9 again, and in nightly FF on Win7. They are in fact both jerky here, but I'm running it all from within Virtual Box, so that might be the reason for loss of performance (or jerkiness).

However, Opera on my Mac is really nailing it. I'd love to know how they manage to achieve such smoothness, and why it differs so noticeably from nightly FF. This isn't only visible in benchmark linked above; on this demo page, for example — http://kangax.github.com/fabric.js/test/demo/ — adding a shape that consists of 8325 paths (from the right sidebar), and then moving it around looks much smoother in Opera than in FF. The FPS reflects it as well (~70 in Opera vs. ~30 in FF).
Comment 6 Boris Zbarsky [:bz] (Out June 25-July 6) 2010-09-22 17:42:46 PDT
> However, Opera on my Mac is really nailing it.

Interesting; I see exactly the same behavior in Opera and Firefox on Mac: smooth animation with one jerk on each rotation when the butterflies are almost upright.  At exactly the same spot in the rotation in both, too.
Comment 7 Juriy "kangax" Zaytsev 2010-09-23 07:32:10 PDT
(In reply to comment #6)
> > However, Opera on my Mac is really nailing it.
> 
> Interesting; I see exactly the same behavior in Opera and Firefox on Mac:
> smooth animation with one jerk on each rotation when the butterflies are almost
> upright.  At exactly the same spot in the rotation in both, too.

Strange.

And what about the other demo (http://kangax.github.com/fabric.js/test/demo/)? When manipulating (dragging, scaling, rotating) shapes on canvas, do you see any difference?  I tried with latest build of Opera 10.70 (9049) and there's clearly a difference here, especially with more complex shapes (say, 5000+ paths).

I'm on Mac OS X 10.6.4 (~3 y/o MBP, 2.6 GHz Core 2 Duo).
Comment 8 Boris Zbarsky [:bz] (Out June 25-July 6) 2010-09-24 21:42:35 PDT
Yeah, like I said Opera's numbers definitely come out higher than ours.  But visually our motion looks smooth even when the site is claiming 12fps; I have to add two copies of the 20k path image to get it down to 6fps and something not-smooth-looking...
Comment 9 Boris Zbarsky [:bz] (Out June 25-July 6) 2010-09-24 21:46:24 PDT
Jeff, do you happen where the from that controls antialiasing for our path-drawing is?  It'd be interested to twiddle it and see how things look.
Comment 10 Boris Zbarsky [:bz] (Out June 25-July 6) 2010-09-24 21:47:39 PDT
One other note.  Still on Mac, Safari performs about as well as we do, as does Chrome.  Which really makes me wonder what Opera is doing differently...
Comment 11 Chris Lord [:cwiiis] 2011-10-07 18:12:00 PDT
Marking this as incomplete - the original demo url no longer exists and no further comments have been added.
Comment 12 Juriy "kangax" Zaytsev 2011-10-07 18:17:52 PDT
I updated URL of test page. 

Also ran it in nightly and performance does seem to be better (comparable to Chrome dev; on my Mac).
Comment 13 Chris Lord [:cwiiis] 2011-10-07 18:21:41 PDT
Great! Changing the status to fixed, in that case. Thanks for the feedback!

Note You need to log in before you can comment on or make changes to this bug.