Speed/Performance Tips?

332 views
Skip to first unread message

Eric

unread,
Aug 15, 2009, 7:17:27 PM8/15/09
to google-excanvas
Hi I'm doing some drawing with javascript and was really happy to find
Explorer Canvas. I'm wondering if there was anyway to get any more
speed out of the rendering. I have a demo and source code here.
http://open.adaptedstudio.com/html5/follow/
It's one object that draws lines toward the mouse.

It runs, but is really slow so I tried the Silverlight package
included in the newest SVN update and it runs better but definitely
slows way down after drawing for a while.
http://open.adaptedstudio.com/html5/follow/index-silverlight.html

Ideally I'd like to be drawing a bunch of lines something like this
link but I guess I would be happy with 1 line in IE.
http://open.adaptedstudio.com/html5/many-lines/

I'm also noticing a huge slow down when I render larger items with
alpha below 100%. Are these all known problems? Is there anything I
can do to work around them and get better performance? Thanks.

- Eric

Fabien

unread,
Aug 16, 2009, 12:29:25 PM8/16/09
to google-excanvas
The ExplorerCanvas lib has been hugely improved, and I don't think
there can be lots of performance improvements now. The silverlight
version is slow too, and it is not really maintained, as we lose lots
of the advantages of a built-in functionality (VML) like events, etc.
I can only suggest you to close the paths with closePath when you have
opened one, it speeds up a little bit the process.
Keep in mind that the implementation of Canvas using VML is and always
will be slower when adding paths to the drawing. Sadly, Canvas may
never be implemented in IE, the only fast solution would be Flash, but
this may not be a good solution.

On 16 août, 01:17, Eric <e...@adaptedstudio.com> wrote:
> Hi I'm doing some drawing with javascript and was really happy to find
> Explorer Canvas. I'm wondering if there was anyway to get any more
> speed out of the rendering. I have a demo and source code here.http://open.adaptedstudio.com/html5/follow/
> It's one object that draws lines toward the mouse.
>
> It runs, but is really slow so I tried the Silverlight package
> included in the newest SVN update and it runs better but definitely
> slows way down after drawing for a while.http://open.adaptedstudio.com/html5/follow/index-silverlight.html
>
> Ideally I'd like to be drawing a bunch of lines something like this
> link but I guess I would be happy with 1 line in IE.http://open.adaptedstudio.com/html5/many-lines/

Ryan Schmidt

unread,
Aug 16, 2009, 3:51:15 PM8/16/09
to google-...@googlegroups.com

On Aug 16, 2009, at 11:29, Fabien wrote:

> The ExplorerCanvas lib has been hugely improved, and I don't think
> there can be lots of performance improvements now. The silverlight
> version is slow too, and it is not really maintained, as we lose lots
> of the advantages of a built-in functionality (VML) like events, etc.

Oh? I was told the Silverlight version was going to be merged with
the VML version, implying to me that it is (or will soon be) exactly
as well-maintained as the VML version, since they will be the same
thing.

> I can only suggest you to close the paths with closePath when you have
> opened one, it speeds up a little bit the process.
> Keep in mind that the implementation of Canvas using VML is and always
> will be slower when adding paths to the drawing.

Yes, I would assume this is correct.

> Sadly, Canvas may
> never be implemented in IE,

What makes you say that? Has Microsoft stated this?

> the only fast solution would be Flash, but
> this may not be a good solution.

Yeah, Flash is nothing like Canvas. I'm certainly not touching it.

Eric Ishii Eckhardt

unread,
Aug 16, 2009, 6:05:31 PM8/16/09
to google-excanvas
Fabien,

Thanks for spotting that the paths were still open. I added closePath
() as per your suggestion and it certainly sped things up. I believe
the Silverlight version is a usable speed now. It's curious to me that
the VML version starts off at a great speed then slows down
dramatically the longer you use it. Do you have any idea why that
would happen or if there is any way I could work around that. I'd
rather use the VML version if possible.In Flash development you could
convert a dynamic drawing to a bitmap to save processing time. Is
there something like that available?

As far as alternatives, yes I've actually done a lot of Flash
development (past and current) but was hoping to place these drawings
under a HTML/Javascript site. Flash almost works for that but has a
couple of deal breaking problems.

Thanks again for the suggestions,
- Eric

Jay Link

unread,
Aug 16, 2009, 6:27:29 PM8/16/09
to google-...@googlegroups.com
> It's curious to me that the VML version starts off at a great speed then slows down
> dramatically the longer you use it. Do you have any idea why that would happen

Not sure if this is the same issue, but if you look at this demo
(which now works in IE8 thanks to a patch by TommyM):

http://www.browserpilot.com/canvascompass.php

... it gradually slows down as well. The reason is that excanvas
creates a new layer every time you draw a new element or make a
rotation. Over time, this create a lot of overhead. To solve it, I
had to create my own "hack" of a library, using excanvas as a base,
that calls progid:DXImageTransform.Microsoft.Matrix() directly.

Maybe not the best method, but it solved my problem.

Ryan Schmidt

unread,
Aug 16, 2009, 6:51:00 PM8/16/09
to google-...@googlegroups.com

On Aug 16, 2009, at 17:27, Jay Link wrote:

>> It's curious to me that the VML version starts off at a great
>> speed then slows down
>> dramatically the longer you use it. Do you have any idea why that
>> would happen
>
> Not sure if this is the same issue, but if you look at this demo
> (which now works in IE8 thanks to a patch by TommyM):
>
> http://www.browserpilot.com/canvascompass.php
>
> ... it gradually slows down as well. The reason is that excanvas
> creates a new layer every time you draw a new element or make a
> rotation. Over time, this create a lot of overhead.

Right. VML is vector drawing, so each vector you draw needs to be
tracked separately. The more vectors you draw, the more vectors it
needs to keep track of and the slower it gets. In contrast, every
browser with a real canvas implementation treats it as a bitmapped
image. You can manipulate the pixels in the bitmap in any way you
like, but in the end, it's just a grid of pixels, and nothing you do
to it will cause there to be more pixels to deal with, so it's always
the same speed.


> To solve it, I
> had to create my own "hack" of a library, using excanvas as a base,
> that calls progid:DXImageTransform.Microsoft.Matrix() directly.
>
> Maybe not the best method, but it solved my problem.

Could you discuss this more? Why is this a hack? What are the
implications of using this method? Why is it "not the best method"?
In what ways would this be better, or worse, than what excanvas does
today? I am not familiar with Microsoft's proprietary drawing
commands so any information you can provide would be helpful.

Jay Link

unread,
Aug 16, 2009, 7:16:28 PM8/16/09
to google-...@googlegroups.com
> Could you discuss this more? Why is this a hack?

It's not beautiful, and it's not finished.

> What are the implications of using this method? Why is it "not the best method"?
> In what ways would this be better, or worse, than what excanvas does today?

I don't support all of canvas; I just needed a way to do unlimited
rotations without getting bogged down by thousands of VML layers.

Here is what I have. You can take out the parts regarding pitch in
the rotate function and make it even smaller:


if (!document.createElement('canvas').getContext) {

(function() {

// alias some functions to make (compiled) code shorter
var m = Math;
var mr = m.round;
var ms = m.sin;
var mc = m.cos;
var abs = m.abs;
var sqrt = m.sqrt;

function getContext() {
return this.context_ ||
(this.context_ = new CanvasRenderingContext2D_(this));
}

var slice = Array.prototype.slice;

function bind(f, obj, var_args) {
var a = slice.call(arguments, 2);
return function() {
return f.apply(obj, a.concat(slice.call(arguments)));
};
}

var G_vmlCanvasManager_ = {
init: function(opt_doc) {
if (/MSIE/.test(navigator.userAgent) && !window.opera) {
var doc = opt_doc || document;
// Create a dummy element so that IE will allow canvas elements to be
// recognized.
doc.createElement('canvas');
doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
}
},

init_: function(doc) {
// find all canvas elements
var els = doc.getElementsByTagName('canvas');
for (var i = 0; i < els.length; i++) {
this.initElement(els[i]);
}
},

initElement: function(el) {
if (!el.getContext) {
el.getContext = getContext;

var attrs = el.attributes;
if (attrs.width && attrs.width.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setWidth_(attrs.width.nodeValue);
el.style.width = attrs.width.nodeValue + 'px';
} else {
el.width = el.clientWidth;
}
if (attrs.height && attrs.height.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setHeight_(attrs.height.nodeValue);
el.style.height = attrs.height.nodeValue + 'px';
} else {
el.height = el.clientHeight;
}
}
return el;
}
};

G_vmlCanvasManager_.init();

function CanvasRenderingContext2D_(surfaceElement) {

// Canvas context properties
this.canvas = surfaceElement;
this.element_ = surfaceElement.firstChild;
//this.element_.style.filter="progid:DXImageTransform.Microsoft.Matrix(FilterType='nearest
neighbor',SizingMethod='auto expand',M11='1.0')";
this.width = this.canvas.clientWidth;
this.height = this.canvas.clientHeight;
}

var contextPrototype = CanvasRenderingContext2D_.prototype;

contextPrototype.fillRect=function(aX,aY,aWidth,aHeight){return;};
contextPrototype.save=function(){return;};
contextPrototype.restore=function(){return;};
contextPrototype.translate=function(aX,aY){return;};
contextPrototype.drawImage=function(img,x,y){return;};

contextPrototype.rotate = function(aRot,pitch) {
var c = mc(aRot);
var s = ms(aRot);

this.element_.style.filter =
"progid:DXImageTransform.Microsoft.Matrix(FilterType='nearest
neighbor',SizingMethod='auto expand',M11=" + c + ", M12=" + (-s) + ",
M21=" + s + ", M22=" + c + ")";
//this.element_.filters.item(0).M11 = c;
//this.element_.filters.item(0).M12 = (-s);
//this.element_.filters.item(0).M21 = s;
//this.element_.filters.item(0).M22 = c;
this.element_.style.left=((this.width-this.element_.offsetWidth)/2)+'px';
if (aRot < 3.14 || aRot > 4.71) {
this.element_.style.top=(((this.height-this.element_.offsetHeight)/2)+pitch)+'px';
} else {
this.element_.style.top=(((this.height-this.element_.offsetHeight)/2)-pitch)+'px';
}
};

// set up externs
G_vmlCanvasManager = G_vmlCanvasManager_;
CanvasRenderingContext2D = CanvasRenderingContext2D_;
})();
}

Jay Link

unread,
Aug 16, 2009, 7:26:04 PM8/16/09
to google-...@googlegroups.com
For rotations only, you can also look up "Universal JavaScript Image
Rotator v1.0", which is also like a bare-bones excanvas.

Eric Ishii Eckhardt

unread,
Aug 16, 2009, 8:23:08 PM8/16/09
to google-excanvas
Hi Jay,

I'm not quite sure I understand how to apply this to a project using
exCanvas.
I looked at the excanvas.js file and figured it would you would need
to override the conditional at 831 so you could get to the filter
statements at lines 854 but I can't figure out how to apply this
nearest neighbor filter. I tried replacing their push state with this
to see if it made any difference

vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
'px 0;filter:progid:DXImageTransform.Microsoft.Matrix
(',
"FilterType='nearest neighbor'", ",
sizingmethod='clip');");

I'm not seeing anything different there. Still slows down
significantly after some use.
Is that how you'd think it should be applied?

- Eric

Jay Link

unread,
Aug 16, 2009, 8:36:33 PM8/16/09
to google-...@googlegroups.com
> I'm not quite sure I understand how to apply this to a project using exCanvas.

Right, you wouldn't. You'd use this instead of excanvas.

I posted the code in response to Ryan's request for more info; it may
not be appropriate for what you need. The main point is, though, that
excanvas creates a new VML element every time you move or rotate your
image, so you will have to come up with a way to circumvent that so
that your app doesn't become progressively slower.


Kind regards,

- Jay

Eric Ishii Eckhardt

unread,
Aug 17, 2009, 3:59:26 PM8/17/09
to google-excanvas
Ah great, thanks for posting it then. Definitely an eye-opener, I
didn't realize exactly what was going on to show "canvas" elements on
IE.
- Eric
Reply all
Reply to author
Forward
0 new messages