2

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

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

如果我淹没了 100 项任务的 Gnatt 图表 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);
    }
}
4

0 回答 0