jQuery,寻找一种更智能的初始化方法

时间:2011-12-01 19:35:28

标签: javascript jquery performance initialization

我正在寻找一种更好的方法来管理大型项目中的全局组件/插件/窗口小部件初始化。它有许多jQuery驱动的组件,我想快速初始化&有效地在浏览互联网之后,我才真正找到了在较小的网站中只有现实/高效的短视示例。

问题

我想找到一个聪明的&摆脱这种优雅的方式:

$(function() { $('.widget-one').widgetOne(); });
$(function() { $('.widget-two').widgetTwo(); });
$(function() { $('.widget-three').widgetThree(); });
$(function() { $('.widget-four').widgetFour(); });

现在在你告诉我之前,让我说明我知道在大多数情况下(但不是全部).widget-one是一个糟糕的选择器,因为它会在旧版浏览器中获取dom中的所有元素并检查上课。

问题是,这些小部件不是一次性的,我可能不知道他们提前存在(在Web应用程序视图中生成,可能是基于逻辑或产品循环的2-3次)

所以以下解决方案已经出来了:

$(function() { $('#WidgetOne').widgetOne(); });

<span id="WidgetOne_12345">...</span>
<script type="javascript">
   $(function() { $('#WidgetOne_12345').widgetOne(); });
</script>

思想

这不是一个新问题,它从第一天开始就存在。它仍然让我感到困惑,即使在这个成熟的水平上,使用jQuery也很难解决这个问题。或者我错过了一些明显的东西。

不幸的是,google-fu在这个问题上的表现非常糟糕,因为每个人都提出了以下两点之一:

  • jQuery的.live().delegate() catch-all事件处理程序。这在基本层面上是可怕的。 .delegate()不会那么糟糕,但这要求插件/小部件/控件/完全由事件驱动。这肯定会在很多情况下起作用,但在其他情况下则不然。它还使得跟随&amp;组织代码非常复杂。我甚至不会进入.live(),对于大型复杂的站点,事件冒泡很慢&amp;当你得到足够的组件时,匹配的查询列表变得很大,使得每个点击/焦点/任何事件在整个页面上整体上逐渐变慢。
  • 涉及像liveQuery这样的插件的解决方案,这是一个非常酷的插件,但它似乎主要是为了解决一个不同的问题(由ajax / dom创建引入新项目的问题) ),并且在需要检查的查询堆栈越多的情况下,仍然会越来越慢。

结论

是更好的方式,我知道必须有一个。我已经厌倦了我的google fu这个主题,但仍然找不到比jQuery 1.3.2更新的想法/概念/例子/讨论或者考虑到宏伟的图片。在一个完美的世界中,这不会是一个问题,因为每个人都会使用具有现代标准的智能浏览器。一个体面的JavaScript引擎,.class查询不会花费很长时间,但遗憾的是情况并非如此。

我正在寻找关于如何解决这个问题的想法,在经历了许多与此相似的SO问题之后,以及关于各种jquery技术的许多文章我觉得如果信息出现在那里它被埋没在许多误报之下。 “101最佳jquery插件”结果在任何搜索中都出现了jQuery。我知道某人已经遇到了这种困境。

想法,链接,例子,欢迎任何事情,只需要有更好的方法。

2 个答案:

答案 0 :(得分:1)

只是头脑风暴,我可以想到一件事会减少你的“选择和初始化”时间,但可能是在开发过程中的痛苦折衷。此外,你不能真正使用这种方法的params,但如果你的情况与你上面描述的情况完全相同,那么这可能是值得的。

如果您认为每个初始化元素都具有相同的类(例如小部件),则可以创建一个初始化小部件的选择器系统。

在HTML中构建类似于这样的结构:

<div class="widget" widgetFunc="widgetOne"></div>
<div class="widget" widgetFunc="widgetTwo"></div>

并且您的jquery init函数将如下所示:

var $widgetInitializerElements = $('.widget');

$.each($widgetInitializerElements,function(){ 
    var initialize = window[$(this).attr('widgetFunc')];

    if(typeof initialize === 'function'){
        $(this).initialize(); 
    }
});

所以这会将你的选择减少到一次,并保持你的jquery非常干净。您只需担心所有可能不可行的HTML元素,如果您需要添加参数来初始化调用,您将遇到麻烦:/

答案 1 :(得分:0)

必须提出的第一个问题是:是否存在真正的性能问题?也就是说,你现在有一个无法使用的应用程序,或者你是否预见到未来的问题。如果是这样,请在出现问题时解决问题 - 可能会更好地利用您的时间。如果是这样,你真的有基准测试来看看你被击中的地方吗?

  

...我知道在大多数情况下(但不是全部).widget-one很糟糕   选择器,因为它将在旧浏览器上获取dom和中的所有元素   检查班级。

这是真的,但也许没关系。如果你看到:

除了IE8及更低版本之外,几乎所有地方都支持

getElementsByClassName。是的,IE8仍然是一个大问题,但这种变化非常迅速。有一个强烈的论点是,想要使用复杂应用程序的人不应该使用旧的浏览器。它根本不值得你花时间。

  

jQuery的.live()或.delegate()catch-all事件处理程序。这只是   从根本上讲是可怕的。

我不同意(可怕?),但是大型应用的更好模型可能是发布/订阅。我在一个复杂的UI应用程序中非常成功地使用了Dojo,并且似乎有一些有用的jQuery插件(例如http://www.novasoftware.com/download/jquery/publish-subscribe.aspx)。这允许全局事件消息传递而不需要委托开销。事件很容易命名,以避免大型应用程序中的冲突。是的,它是由事件驱动的,但如果您想在大型应用中保持性能,这一点非常重要。

除此之外,改进类选择器的最快方法是添加标签,例如:

$('p.widget-one')

而不是

$('.widget-one')