如果一个函数被多次调用,将选择器缓存到函数中是否会提高性能?

4

好的,我想我知道这个问题的答案,需要确认一下。因此,我有一个选择器,它只被使用了一次,但是它被用在一个被多次调用的函数内部。从性能的角度来看,由于该选择器每次调用函数时都要重新搜索,因此缓存该选择器可能会更好(尽管略微)?

换句话说,如下所示...

function testFunction() {
  alert($("#input").val())
}

$("#a").click(function() {
  testFunction()
})

$("#b").click(function() {
  testFunction()
})

$("#c").click(function() {
  testFunction()
})

...不如以下方法执行效率高

input = $("#input")

function testFunction() {
  alert(input.val())
}

$("#a").click(function() {
  testFunction()
})

$("#b").click(function() {
  testFunction()
})

$("#c").click(function() {
  testFunction()
})

你可以缓存 jQuery 对象,以避免多次调用 jQuery()。你也可以通过检查使用每种模式调用函数所需的总时间来确定哪种方法更“高效”,请参见在 jQuery 中,使用 find() 而不是 > 选择器更有效吗?。没有基准测试,这个问题只是基于猜测,而不是事实。 - guest271314
如果涉及性能问题,请尝试使用.click(testFunction)。您正在定义3个具有相同签名的匿名函数。您应该使用1个命名函数并在所有处理程序中使用它。 - Rajesh
2个回答

1
显然,jQuery()的调用完成所需的总时间比对jQuery对象的变量引用要少。最后一次运行记录如下:
  • jQuery(): 16.580毫秒
  • 缓存的jQuery()对象: 22.885毫秒

(function() {

  function testFunction() {
    $("#input").val()
  }

  console.time("jQuery()");

  for (let i = 0; i < 10000; i++) {
    testFunction()
  }
  
  console.timeEnd("jQuery()");
  
})();

(function() {

  let input = $("input");

  function testFunction() {
    input.val()
  }

  console.time("cached jQuery() object");

  for (let i = 0; i < 10000; i++) {
    testFunction()
  }
  
  console.timeEnd("cached jQuery() object");
  
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<input>


有趣的是,当使用jQuery版本3.1.1时,两个模式之间的持续时间增加了大约两秒钟,其中jQuery()调用仍然在“缓存”的jQuery对象引用之前完成。 - guest271314
哇,这真是令人惊讶!感谢您做到了这一点,并向我展示了如何自己运行测试。有任何想法为什么会这样吗?诚然这并不是很合乎逻辑... - james
@james 不确定逻辑如何涉及。也许是假设。从这里的视角来看,事实很清楚。不确定确切的原因;对象查找的成本?不过在这方面尽量避免猜测。您可以在 https://github.com/jquery/jquery 上提交问题,询问 jQuery 库的作者和维护者提供他们从中得出的模式和原始数据的评估。虽然可能不是存储库本身所讨论的主题,但仍是有趣的经验结果。 - guest271314

0

是的,你说得对,第二个比第一个更有效率,因为

在第一个中,首先要选择输入字段,然后才能找到该输入字段,并选择它,每次函数调用都会发生这种情况。

但在第二种情况下,选择器在页面加载时只选择一次,然后通过变量引用该选择器,不会在每次调用中查找该输入字段。这就是为什么第二个更有效率。

        <input value='Value' id='input'><br>
        <span id='tt'>dssd</span><br>
        <span id='t1'></span><br>
        <span id='t2'></span>

还有Jquery:

 function testFunction1() {
        var t=$("#input").val()
        $("#tt").html(t);
    }
    console.time("jQuery() object");
    var t1=performance.now();
    for (var i = 0; i < 50000; i++) {
        testFunction1()
    }
    console.timeEnd("jQuery() object");

    var t2=performance.now();
    t2=t2-t1;
    $("#t1").html('Without selector variable:- '+t2);
    var input = $("input");
    function testFunction2() {
        var t=input.val();
        $("#tt").html(t);
    }
     t1=performance.now();
    console.time("cached jQuery() object");
    for (var i = 0; i < 50000; i++) {
        testFunction2()
    }
     t2=performance.now();
    console.timeEnd("cached jQuery() object");
    t2=t2-t1;
    $("#t2").html('With selector variable:- '+t2);

在这里检查:-点击这里


"是的,你说得对,第二个比第一个更有效率。" 但这并不准确,如在 https://dev59.com/_qLia4cB1Zd3GeqPimjH#44427954/ 中所示。"这就是为什么第二个更有效率。" 你能否在 stacksnippets、jsfiddle、plnkr 或 jsperf 上重现第二个模式比第一个模式完成时间更短的情况? - guest271314
“但是你为什么这么说?”像这样说什么?事实?你能展示并证明“第二个比第一个更有效”这个命题吗?或者,你只是在猜测哪种模式更“有效”?你所说的“更有效”是什么意思? - guest271314
1
只需检查此 https://jsfiddle.net/Bibhudatta_sahoo/ukscnxme/6/ 然后我们才能明白为什么我说它更有效率。 - Bibhudatta Sahoo
你应该在你的回答中使用 stacksnippets 发布代码。 - guest271314

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接