一次又一次使用相同的查询选择器是否会降低性能?

时间:2018-09-17 04:48:26

标签: javascript jquery garbage-collection javascript-engine

在文档中搜索相同查询选择器的性能成本是否总计为一个重要查询选择器,还是正在使用中的JavaScript库(例如jquery)或JavaScript引擎或浏览器中的某些代码管道?引擎-缓存查询选择器。

$(document).ready(function() {

  var foo = $("#foo");

  doThis();
  doThat();
  thenDoThat();
  ...

  function doThis() {
    $("#foo")...
    ...
  }

  function doThat() {
    $("#foo")...
    ...
  }

  function thenDoThat() {
    $("#foo")...
    ...
  }

  ...
});

我确实了解对象的寿命,特别是。在垃圾收集的环境中。因此,关于对象的范围将决定其生存期的答复并不能完全满足我的好奇心,因为事实很明显。

我的问题确实是,如果我一次又一次访问$("#foo")

  1. 这将花费大量的CPU时间,因此会以适当的级别将其缓存在我的代码中,从而避免了此类费用,或者

  2. 某些代码已将其缓存,或

  3. 无论完成多少次,它都可以忽略不计吗?

1 个答案:

答案 0 :(得分:2)

是的,这会对性能产生影响。每次$(selector)运行时,都必须构造一个新的jQuery对象。也就是说,除非您在短时间内运行大量,否则影响很小。例如:

const t1 = performance.now();

for (let i = 0; i < 300000; i++) {
  const html = $('div').html();
}

const t2 = performance.now();

const div = $('div');
for (let i = 0; i < 300000; i++) {
  const html = div.html();
}

const t3 = performance.now();

console.log(t2 - t1);
console.log(t3 - t2);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>foo</div>

构造jQuery对象确实花费了非零的CPU时间,但这仍然不多。如果您要做担心效率,则可以只使用标准Javascript,它会比jQuery方法有更多的改进(甚至比保存对jQuery对象的引用要好)。

const t1 = performance.now();
for (let i = 0; i < 300000; i++) {
  const html = $('div').html();
}
const t2 = performance.now();

const $div = $('div');
for (let i = 0; i < 300000; i++) {
  const html = $div.html();
}
const t3 = performance.now();

for (let i = 0; i < 300000; i++) {
  const html = document.querySelector('div').innerHTML;
}
const t4 = performance.now();

const div = document.querySelector('div')
for (let i = 0; i < 300000; i++) {
  const html = div.innerHTML;
}
const t5 = performance.now();

console.log('jQuery re-selection', t2 - t1);
console.log('jQuery saving reference', t3 - t2);
console.log('vanilla re-selection', t4 - t3);
console.log('vanilla saving reference', t5 - t4);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>foo</div>