Ajax之前是否请求ASAP,或者也准备好文档?

时间:2012-11-29 21:53:48

标签: javascript jquery ajax optimization

我正在优化一个页面,但我无法分辨这些结果之间的差异(第一个显然更快,但我不确定它是否会减慢页面渲染的速度):

这个将尽快启动请求,并在文档就绪时修改DOM:

<script>
$.ajax({
    url: '/some-url',
    success: function() {
        $(document).ready(function() {
            // do something
        });
    }
});
</script>
</body>

这个将开始准备文件的请求:

<script>
$(document).ready(function() {
    $.ajax({
        url: '/some-url',
        success: function() {
            // do something
        }
    });
});
</script>
</body>

推荐哪一个?

3 个答案:

答案 0 :(得分:10)

此处的最佳做法是尽快启动 Ajax请求,但仅在文档准备就绪时才开始修改DOM( DOMContentLoaded )。为此,您可以使用与jQuerys扩展 jXHR 对象连接的jQuerys 延迟对象

<script>
    var req      = $.ajax({}),
        docReady = jQuery.Deferred();

    $(function() {
        docReady.resolve();
    });

    $.when( req, docReady ).done(function( data ) {
        // read the returned data and modify the DOM
    });
</script>

等待启动请求直到DOM准备就绪是浪费时间。 XHR请求对于DOM的最新情况没有任何兴趣和兴趣。


完全解耦这两件事更有意义。如果由于某种原因DOM在准备好之前需要很长时间,那么您就不会浪费时间让 HTTP请求运行并收集其数据。反过来说,如果请求非常慢,你也会浪费时间。所以你现在的片段就像​​是

DOM ready    
           -> XHR request    
                          -> Do something useful

而我的例子就像

DOM ready    
XHR request
            -> Do something useful as soon as the DOM and request are ready

答案 1 :(得分:1)

由于$.ajax不以任何方式依赖于DOM,因此没有理由不能尽快调用它。在这种情况下,我会把它放在<head>部分,并在其依赖脚本/脚本文件完成后立即调用它(至少意味着jQuery库)。更快地解雇AJAX请求意味着响应能够更快地返回 - 它可能不是实际发生的情况,但这并不重要。

确保在success内部已准备好DOM,这对您的代码来说是最快捷的执行方式。使用$.when( req ).done(function () {})创建了另外两个jQuery方法调用,这些调用可能会或可能不会显着延迟success代码的执行 - 它会延迟它,但它可能是无关紧要的。

此外,您在document.ready方法中使用success的示例会创建可能性,表明DOM已准备好并且可以立即执行(在AJAX请求的情况下)在DOM完全加载之前完成,这是我不希望的。在jAndy的例子中,document.ready$.ajax之后立即运行,保证它将为正在准备的文档绑定一个事件处理程序...这意味着它必须被存储(导致DOM稍后就绪,然后在事件发生后再查找并执行。同样,差异是可能性保证 ......并且所有这些都可能无关紧要(只要您不使用第二个示例)。

答案 2 :(得分:-2)

在这个简单的例子中,两个版本都应该这样做。哪一个更好取决于您的页面和其他脚本。 如果您的脚本稍微复杂一点,并且您需要将数据传递给必须从页面获取的ajax-request,并且此时您的页面还没有准备好 - 那么您将遇到错误。

另一件事是,页面上的任何脚本都会在处理浏览器时阻止浏览器,因此一个没有doc-ready的更复杂的代码可能会导致页面呈现过程中的短暂停止。 在大多数情况下,我更喜欢让浏览器加载所有HTML,CSS和JS - 然后开始我的渐进增强和加载其他内容。

但是再次 - 在这个简单的例子中 - 我没有看到太多不同。