2

SVG + JS のパフォーマンスを調査するために、単純なjsfiddle の例 (多くの四角形を溺死させ、それぞれに固有のイベントをバインドする) を作成します。

10x10 = 100 エレメントの場合、パフォーマンスは優れていますが、100x300 の場合、Firefox は領域を構築するために 10 秒でフリーズし、イベントの完了には 1 秒の遅延が生じます。

100 タスクのグナット チャートを 1 年間 (356 日) 溺れさせると、同じ問題が発生します。

パフォーマンスを向上させる方法はありますか?

私が見る 1 つの方法は、クロージャーを避けて汎用イベント ハンドラーを使用することです。

もう 1 つの方法は、単一のイベントを SVG にバインドし、(X,Y) 座標を計算して、実行するアクションを決定することです。

もう一度、SVG を DOM に配置する前にビルドします。

他の提案はありますか?

フィドルがダウンしていた場合の完全なコードは次のとおりです。

<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