It takes IE (6 & 7) a long time to draw a linestring consisting of many coordinates (3000+).
A little investigation in Renderer/VML.js (drawLine) showed that the biggest slowdown was the concatenation of the 'path' string.
Apparently IE doesn't deal well with lots of concatenations and/or big strings. I managed to reduce the time to create the path string dramatically from 40+ seconds to 1 second by mimicking a StringBuffer (put path string pieces in array and join them in the end).
So, in short, this:
path += " " + x.toFixed() + "," + y.toFixed() + " l ";
is replaced with this:
path.push( " " + x.toFixed() + "," + y.toFixed() + " l ");
The same slowdown most probably applies to the other drawing methods in this class.
My question is: what would be the best way to tackle this?
Suggested option:
- create a OpenLayers.Util.StringBuffer object (with append and toString methods)
- create a 'path' object that extends StringBuffer that will be used by VML.js and possibly SVG.js
No diff attached yet. Waiting for outcome of email discussion. See code example below for understanding fix (few extra optimisations in there):
Old behavior:
drawLine: function(node, geometry, closeLine) {
this.setNodeDimension(node, geometry);
var resolution = this.getResolution();
var path = "m";
for (var i = 0; i < geometry.components.length; i++) {
var x = (geometry.components[i].x/resolution);
var y = (geometry.components[i].y/resolution);
path += " " + x.toFixed() + "," + y.toFixed() + " l ";
}
if (closeLine) {
path += " x";
}
path += " e";
node.path = path;
},
New behaviour:
drawLine: function(node, geometry, closeLine) {
this.setNodeDimension(node, geometry);
var resolution = this.getResolution();
var components = geometry.components.length;
var path = [];
path.push("m ");
for (var i = 0; i < components; i++) {
var x = (geometry.components[i].x/resolution).toFixed();
var y = (geometry.components[i].y/resolution).toFixed();
path.push( " " + x + "," + y + " l " );
}
if (closeLine) {
path.push(" x");
}
path.push(" e");
node.path = path.join("");
},