具有大量元素的浏览器SVG的性能

时间:2013-08-30 13:03:34

标签: javascript performance browser svg

我制作了一个简单的jsfiddle示例(它淹没了许多矩形并将唯一事件绑定到每个矩形)以探索SVG + JS性能。

10x10 = 100元素性能优越但100x300我的Firefox在10秒内被冻结以构建区域,事件有1秒延迟完成。

如果我将Gnatt图表淹没100个任务1年(356天),我也有同样的问题!

有没有办法改善表现?

我看到的一种方法是避免使用闭包并使用通用事件处理程序。

另一种方法是将单个事件绑定到SVG并计算(X,Y)坐标以确定要执行的操作。

再次将SVG构建到DOM之前构建SVG。

还有其他建议吗?

如果小提琴失败,这里有完整的代码:

<div id="rect"></div>
<div id="hint"></div>

var wN = 50;
var hN = 50;

var w = 600;
var h = 400;

////////////////////////////////////////////////////////////////
// Common actions on SVG object.
////////////////////////////////////////////////////////////////

function SVGlibBase() {
    this.value = null;
}
SVGlibBase.svgNS = "http://www.w3.org/2000/svg";
// prim.attr("name") return attribute value
// prim.attr("name", "value") set attribute name to value, chaining
// prim.attr("name", null) remove attribute, chaining
// prim.attr({"name1", "value1", "name2", "value2", ...}) set attributes, chaining
SVGlibBase.prototype.attr = function(name, value) {
    if (typeof name === "object") {
        for (var i in name) {
            this.attr(i, name[i]);
        }
        return this;
    }
    if (typeof name === "string") {
        if (typeof value === "string" || typeof value === "number") {
            this.value.setAttribute(name, value);
        } else if (value === null) {
            this.value.removeAttribute(name);
        } else if (typeof value === "undefined") {
            return this.value.getAttribute(name);
        }
        return this;
    }
    throw new Error("name is absent");
}
// Put object to container.
SVGlibBase.prototype.putTo = function(container) {
    container.value.appendChild(this.value);
    return this;
}

////////////////////////////////////////////////////////////////
// Main drawing area.
////////////////////////////////////////////////////////////////

function SVGlibObj(w, h) {
    this.value = document.createElementNS(SVGlibBase.svgNS, "svg");
    this.value.setAttribute("version", "1.2");
    this.value.setAttribute("baseProfile", "tiny");
    this.value.setAttribute("width", w);
    this.value.setAttribute("height", h);
    this.value.setAttribute("viewBox", "0 0 " + w + " " + h);
}
SVGlibObj.prototype = Object.create(SVGlibBase.prototype);
SVGlibObj.prototype.putTo = function(container) {
    container.appendChild(this.value);
    return this;
}
SVGlibObj.prototype.put = function(child) {
    this.value.appendChild(child.value);
    return this;
}

////////////////////////////////////////////////////////////////
// Rectangle.
////////////////////////////////////////////////////////////////

function SVGlibRect(x, y, w, h) {
    this.value = document.createElementNS(SVGlibBase.svgNS, "rect");
    this.value.setAttribute("x", x);
    this.value.setAttribute("y", y);
    this.value.setAttribute("width", w);
    this.value.setAttribute("height", h);
}
SVGlibRect.prototype = Object.create(SVGlibBase.prototype);

var svg = new SVGlibObj(w, h).putTo(document.getElementById("rect"));

function xy2c(x, y) {
    return "rgb(" + (x*113 & 0xff) +","+ (y*23 & 0xff) +","+ ((x*y*7) & 0xff) + ")";
}

function get_e(i, j) {
    return function() {
        console.log("%d x %d", i, j);
        document.getElementById("hint").innerHTML = i+" X "+j;
    }
}

var dw = w / wN;
var dh = h / hN;
for (var i = 0; i < wN; i++) {
    for (var j = 0; j < hN; j++) {
        var rect = new SVGlibRect(dw*i, dh*j, dw, dh).attr("fill", xy2c(i, j)).putTo(svg);
        rect.value.addEventListener("mouseover", get_e(i, j), false);
    }
}

0 个答案:

没有答案