我制作了一个简单的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);
}
}