IE为什么要等到调用堆栈为空才发送POST AJAX请求? [英] Why does IE wait till the call stack is empty to send POST AJAX requests?

查看:68
本文介绍了IE为什么要等到调用堆栈为空才发送POST AJAX请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下由几个不同的小部件组成的应用程序.触发事件后,小部件会清除其当前数据,执行AJAX请求,然后在响应返回时放入新信息.

Imagine in application composed of several different widgets. When an event is fired, the widgets clear out their current data, execute an AJAX request, then put in the new information when the response comes back.

以下是触发该事件时发生的情况的简化示例:

The following is a simplified example of what happens when that event is fired:

for (var i = 0; i < 10; i++) {
    // Do an AJAX post
    $.ajax(document.location.href, {
        data: {
            name: ‘Zach Gardner’
        },
        method: ‘POST’
    });
    // Do some expensive DOM stuff
    for (var j = 0; j < 100; j++) {
        var el = document.createElement(‘div’);
        document.body.appendChild(el);
        for (var k = 0; k < 100; k++) {
            var child = document.createElement(‘div’);
            el.appendChild(child);
            el.removeChild(child);
        }
    }
}

这是上面代码的JSFiddle

如果打开Fiddler并在Chrome中运行它,您会发现AJAX请求很快完成.

If you open up Fiddler, and run it in Chrome, you'll notice the AJAX requests complete rather quickly.


(来源: zgardner.us )


(source: zgardner.us)

但是,如果您在IE中执行相同的操作(在10、11、12预览版中进行了测试),您会注意到请求所花的时间更长:

But if you do the same thing in IE (tested in 10, 11, 12 preview), you'll notice that the requests take much longer:


(来源: zgardner.us )


(source: zgardner.us)

我们发现,当jQuery执行对xhr的send方法的调用时,IE将创建请求.但是它会保留该请求,直到调用堆栈被清空为止.

What we've found is that IE will create the request when jQuery executes a call to the xhr's send method. But it holds onto the request until the call stack has been emptied.


(来源: zgardner.us )


(source: zgardner.us)

请注意ClientBeginRequest和ClientDoneRequest之间的重大滞后.我们发现ClientDoneRequest始终在线程结束的几毫秒内.

Notice the significant lag between ClientBeginRequest and ClientDoneRequest. We've found that ClientDoneRequest is always within a few milliseconds of the thread ending.

这仅适用于POST AJAX请求. GET的ClientBeginRequest和ClientDoneRequest总是彼此相距不超过几毫秒.

This only happens for POST AJAX requests. The ClientBeginRequest and ClientDoneRequest for GETs are always within a few milliseconds of each other.

此外,请注意,IE的开发工具也会显示此问题:

Also, note that this problem also shows up with IE's Dev Tools:


(来源: zgardner.us )


(source: zgardner.us)

如果您检查单个请求,则可以第二次启动,这是它发送请求正文时所花的时间:4.32秒:

If you inspect an individual request, you can the second Start, which is when it sends the body of the request, took 4.32 seconds:


(来源: zgardner.us )


(source: zgardner.us)

为什么会这样?

有关更多详细信息,请参见我的博客帖子.解释.

See my blog post for a more detailed explanation.

推荐答案

由于Internet Explorer的源代码不是免费提供的,因此只有IE开发人员才能更详细地回答您的问题.

Since Internet Explorer's source code isn't freely available, only an IE developer should be able to answer your question with more degree of detail.

Web浏览器使用执行队列来实现异步.只有一个线程,它可以处理来自UI和AJAX(以及其他任务源)的排队任务.也就是说,它只能一次执行一次操作.

Web browsers implement asynchronousity using an execution queue. There's a single thread and it attends enqueued tasks from the UI and AJAX (and other task sources). That is, it can only happen an operation at once.

另一方面,UI的优先级高于任何其他任务,因此,应该在AJAX调用之前执行DOM操作.当您发送AJAX请求时,发送请求的CPU时间可能会很短,但是如果您进行大量的UI工作,则结束整个AJAX请求的时间可能会更长一些,因为在优先级方面UI > AJAX.

In the other hand, UI is prioritized over any other task, thus, DOM operations should be executed before an AJAX call. When you send an AJAX request, maybe there's a small CPU time to send the request, but if you do a lot of UI work, it might take longer to end the whole AJAX request because UI > AJAX in terms of prioritization.

您在问题中描述的情况是Internet Explorer中的实现细节. Chrome和Firefox在任务优先级方面可能会更好地工作,但是无论如何,我不认为在发送一堆AJAX请求时尝试一次附加100个DOM元素的情况. 您是需要优化代码,而不是期望Web浏览器优化学术/前沿案例的人.

The case you're describing in your question is an implementation detail in Internet Explorer. Chrome and Firefox might work better in terms of task prioritization, but anyway, I don't imagine a case where you try to append 100 DOM elements at once while you send a bunch of AJAX requests. It's you who needs to optimize your code rather than expecting your Web browser to optimize an academic/edge case.

例如,您可能不会将100个DOM元素一一添加到文档元素中.您可以创建一个容器(即document.createElement("div")),然后在不将容器附加到DOM的情况下添加100个元素,以最终将整个容器添加到DOM.这将在一次绘画事件中添加这100个元素,这比较便宜,并且由于任务优先级的原因,像AJAX之类的其他事物应在更短的时间内执行.

For example, you might not add 100 DOM elements one by one to the document element. You might create a container (i.e. document.createElement("div")), and later add 100 elements while container isn't attached to the DOM to finally add the whole entire container to the DOM. This will add these 100 elements in a single paint event, which is cheaper and other stuff like AJAX should be executed in less time because of task prioritization.

此外,我不确定您是否知道Fiddler放慢速度的请求(这是调试器,会对性能造成影响).

Also, I'm not sure if you know that Fiddler slow-downs requests (it's a debugger, there's a performance hit).

您应该在此处查看其他问答:

You should take a look at this other Q&A here in SO: How does JavaScript handle AJAX responses in the background?

这篇关于IE为什么要等到调用堆栈为空才发送POST AJAX请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆