使用setTimeout来提高响应能力

cbp*_*cbp 9 javascript performance

在寻求提高页面性能时,我之前没有提到的一种技术是使用setTimeout来阻止javascript阻止页面的呈现.

例如,假设我们有一个特别耗时的jQuery与html内联:

$('input').click(function () {
    // Do stuff
});
Run Code Online (Sandbox Code Playgroud)

如果这段代码是内联的,那么当jquery忙于将点击处理程序附加到页面上的每个输入时,我们就会阻止页面的感知完成.

生成一个新线程是明智的:

setTimeout(function() {
    $('input').click(function () {
        // Do stuff
    })
}, 100);
Run Code Online (Sandbox Code Playgroud)

我能看到的唯一缺点是,用户在附加点击处理程序之前点击元素的可能性更大.但是,这种风险可能是可以接受的,即使没有setTimeout,我们也有一定程度的风险.

我是对的,还是我错了?

Dav*_*ang 11

实际的技术是使用setTimeout0的时间.

这是有效的,因为JavaScript是单线程的.超时不会导致浏览器生成另一个线程,也不保证代码将在指定的时间内执行.但是,代码将在以下两者中执行:

  1. 指定的时间已过.
  2. 执行控制权交还给浏览器.

因此setTimeout,使用0的时间调用可以被视为临时屈服于浏览器.

这意味着如果你有长时间运行的代码,你可以通过定期屈服来模拟多线程setTimeout.您的代码可能如下所示:

var batches = [...]; // Some array
var currentBatch = 0;

// Start long-running code, whenever browser is ready
setTimeout(doBatch, 0);

function doBatch() {
    if (currentBatch < batches.length) {
        // Do stuff with batches[currentBatch]

        currentBatch++;
        setTimeout(doBatch, 0);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:虽然在某些情况下了解这种技术很有用,但我非常怀疑在你描述的情况下你需要它(在DOM上准备事件处理程序).如果性能确实是个问题,我建议通过调整选择器来寻找改善实际性能的方法.

例如,如果页面上只有一个包含<input>s的表单,则提供<form>一个ID,然后使用$('#someId input').

  • 虽然我没有用最现代的浏览器来测试这个,但过去使用0作为超时我遇到了一些问题:某些浏览器将其短路到同步执行.因此我总是使用1. (3认同)
  • @Ates:你所描述的应该*永远不会发生.什么浏览器?什么背景? (2认同)

ctc*_*rry -1

您是对的,“错过”点击的可能性更大,但由于超时值较低,这种可能性很小。