如何创建jQuery插件来缓存jQuery对象,如下所示

时间:2015-03-21 14:03:10

标签: javascript jquery caching

如果e类型为HtmlElement

,则问题是

这会导致性能问题$(e) !== $(e),而不是重用jQuery对象,每当我们调用$(e)时,jQuery都会创建新对象

$(e).attr(....
$(e).css(...
$(e).find(....

对于每个语句,当我们执行

时,会创建新的jQuery对象并提高性能
var $e = $(e);
$e.attr(....
$e.css(...
$e.find(....

所以我决定通过重写$来缓存,如下所示。而不是改变巨大的代码。

var $old = window.$;

var $ = function(o){
    if(typeof HTMLElement === "object" ? o instanceof HTMLElement : o 
        && typeof o === "object" 
        && o !== null 
        && o.nodeType === 1 
        && typeof o.nodeName==="string"){
        o.__$ = o.__$ || $old(o);
        return o.__$;
    }
    return $old(o);
};

$.prototype = $old.prototype;

$(e) === $(e)返回true后,在页面上下文中,如果多次调用,则运行速度非常快。

然而,$.trim, $.isArray所有函数都消失了,我有很大的代码库依赖于jQuery,但我希望通过缓存来提高jQuery的速度。

1 个答案:

答案 0 :(得分:0)

虽然我现在看到你想要实现的目标,但我不认为在这里修改jQuery是解决方案。

在您的示例代码中

$(e).attr(...);
$(e).css(...);
$(e).find(...);

这确实会导致jQuery重新评估选择器3次,是的,这比缓存时慢。但是我认为修改jQuery来进行缓存是错误的解决方案。

通常在编程中我们将获取的结果“缓存”到变量然后对其进行修改(而不是重新获取)

var e = $(e);
e.attr(...);
e.css(...);
e.find(...);

或者使用jQuery的链接,你可以在一行中完成所有操作

$(e).attr(...).css(...).find(...); //(wrap if desired)

我认为将jQuery的行为改为自动缓存实际上会促使人们不去思考/关心所编写代码的性能。

e.g。如果有一个“酷JS库”做了SQL ...

$SQL("SELECT * FROM TABLE foo WHERE name='blah'").updateTimestamp();
$SQL("SELECT * FROM TABLE foo WHERE name='blah'").set('type','raincoat');
$SQL("SELECT * FROM TABLE foo WHERE name='blah'").set('price',57.50);

很明显,由于不断重新选择结果,因此性能会很糟糕。我认为使用jQuery开发人员只需要记住选择器正在运行一个查询(有时非常快!)但仍然是一个查询,因此如果不需要它就不应该多次调用它。

(PS我在开玩笑,建议客户端SQL查询库是一件好事,与SELECT *同上......这只是一个例子)