我正在为我的一个项目开发一个小型 jQuery 式库,到目前为止一切都很好,但是我遇到了一些性能问题,我似乎无法弄清楚为什么虽然我有一些想法,但首先,这里是有问题的代码(简化以显示实际问题):
演示:http: //jsbin.com/umemot/1/edit
(function(doc, win) {
// Utils:
var AP = Array.prototype;
function _toArray(obj) {
return AP.slice.call(obj);
}
function _curry(fn, that) {
return function() {
return fn.apply(that || arguments[0], AP.slice.call(arguments));
};
}
function _flatten(arr) {
return AP.concat.apply([], arr);
}
function _uniq(arr) {
return arr.filter(function(el, i) {
return arr.indexOf(el) == i;
});
}
function _removeEmpty(arr) {
return arr.filter(function(v) { return v; });
}
// Proto:
function Lib(selector) {
this.el = this._init(selector);
}
function lib(selector) {
return new Lib(selector);
}
// Lib:
Lib.prototype = {
_init: function(selector) {
return _toArray(doc.querySelectorAll(selector));
},
_with: function(fn) {
var result = [];
this.each(function() { result.push(fn.call(this, this)); });
this.el = _removeEmpty(_uniq(_flatten(result)));
return this;
},
_matches: function(selector) {
return this._with(function() {
var parent = _toArray(this.parentNode.querySelectorAll(selector));
return ~parent.indexOf(this) && this;
});
},
each: function(fn) {
return this.el.forEach(_curry(fn)), this;
},
find: function(selector) {
return this._with(function() {
return _toArray(this.querySelectorAll(selector));
});
},
children: function(selector) {
return this._with(function() {
return _toArray(this.children);
});
},
filter: function(selector) {
return this._matches(selector);
}
};
win._ = lib;
}(document, window));
我使用它非常像 jQuery:
_('#outer').find('div').children().filter('a');
与 jQuery 相比,我遇到的问题是性能大幅下降,您可以在此处看到http://jsperf.com/lib-vs-jquery-69。
这就是我的想法:
- 所有那些 ES5 数组方法都在减慢它的速度
- 某种垃圾收集问题?也许我泄漏了什么?
- 该
_matches
方法是否足够有效?
以上所有可能导致性能比 jQuery 慢 60% 还是我的实现是错误的?有任何想法吗?
编辑:我正在其他浏览器中进行测试,似乎只是 Chrome 的一个“大问题”......虽然 Opera 说它慢了 20%,Firefox 只有 3%......