OpenLayers OpenLayers

Ticket #1095 (closed task: fixed)

Opened 1 year ago

Last modified 1 year ago

VML rendering in IE is slow with big geometries

Reported by: rdewit Assigned to:
Priority: minor Milestone: 2.6 Release
Component: Renderer.VML Version: 2.5
Keywords: Cc:
State:

Description

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("");
    },

Attachments

1095.00.patch (3.4 kB) - added by fredj on 12/11/07 03:00:03.
replace all string concatenation, tests pass on IE
vml.patch (4.2 kB) - added by tschaub on 12/11/07 19:04:43.
vml path creation
vml.01.patch (3.3 kB) - added by fredj on 12/13/07 03:28:49.
update tschaub's patch to the last svn version, fix a typo in drawLine (join 'parts' array not 'path')

Change History

12/11/07 00:42:35 changed by crschmidt

Can someone turn this into a patch?

12/11/07 03:00:03 changed by fredj

  • attachment 1095.00.patch added.

replace all string concatenation, tests pass on IE

12/11/07 03:00:21 changed by fredj

  • keywords set to review.

12/11/07 03:06:44 changed by fredj

Does the same technique needs to be applied to the SVG renderer ?

12/11/07 17:26:15 changed by rdewit

fredj: you're quick! Thanx for that! As far as I know the SVG renderer doesn't use string concatenations.

12/11/07 19:04:43 changed by tschaub

  • attachment vml.patch added.

vml path creation

12/11/07 19:08:35 changed by tschaub

  • keywords changed from review to commit.

Please commit this. If you like, review and commit my second patch. Pretty much the same thing - except the array in drawLine is of known size, and assignment by index is faster than push.

12/13/07 03:28:49 changed by fredj

  • attachment vml.01.patch added.

update tschaub's patch to the last svn version, fix a typo in drawLine (join 'parts' array not 'path')

12/13/07 05:24:51 changed by fredj

  • keywords deleted.
  • status changed from new to closed.
  • resolution set to fixed.

(In [5392]) Speed up geometry rendering with VML by replacing string concatenation by array concatenation and joining. Thanks tschaub for the patch optimization and review. (Closes #1095)