如何优化基于Web的应用程序以防止由于后台多个异步请求导致的延迟?

时间:2011-06-24 06:29:31

标签: javascript ajax optimization ria

我正在设计基于瘦服务器客户端MVC架构的模块化RIA。目前,该应用程序仅完成了10%的程度,因此合并设计更改还为时不晚。

应用程序的设计方式使其最初以非常小的占用空间加载,并且根据用户执行的操作,异步提取大量数据。这些数据可能包括存储在我的服务器中的数据以及来自第三方Web服务的数据,包括社交网络和微博服务。

然而,我担心的是,在后台运行的多个数据重ajax请求是否可能使浏览器停滞不前?我最近在一些社交内容聚合服务中发现了一些严重的延迟问题,并且在分析客户端代码时,我很惊讶客户端的应用程序占用空间很小,在300KB以内。但是,当经常运行应用程序时,浏览器(包括Firefox和IE)都会挂起并花费几秒钟来恢复。在分析异步请求时,似乎应用程序同时从gmail,facebook和twitter获取用户内容并将它们推入DOM并占用了大量内存资源。

如果有人能指出一些指导方针/最佳做法来防止此类问题,那就太棒了。编写一个自定义包装器脚本是可取的,该脚本以预先指定的重要性顺序依次加载后台内容,而不是并行加载它们,这最终可能导致多个回调并行执行。

任何建议都会受到高度赞赏。

2 个答案:

答案 0 :(得分:2)

一个解决方案,这不是针对所有情况的杀手级解决方案,但一种解决方案是在服务器端委托内容聚合,而不是在最终浏览器中委托内容。

可以使用 ESIGates 完成此操作。其中一个是Varnish-Esi,但它并不涵盖整个ESI specificationThis one (esigate.org)也是开源的,可能有更好的覆盖范围(尚未测试)。 ESI系统意味着您的应用程序布局可以是具有不同缓存策略(TTL)和不同提供程序的各种块的组合。 ESI服务器将占用您最初被推送到最终浏览器的流量的一部分,因此将花费您更多的带宽,但至少您将获得更多控制

至少它可以改善服务器上异步数据加载的缓存策略,这样可以加快最终浏览器的响应时间(更好的响应时间,更少的并行工作)。

现在,在您的页面上,在优先级方面,您应该确定哪些是最重要的内容,用户可以开始使用的内容,以及什么是“装饰”(嗯,这意味着您的服务是一个很好的信息/噪音比,如果您的网站除社交网络聚合外没有提供任何问题)。

我认为,由于您的应用程序是一个小型静态应用程序,并且有大量异步加载的数据,因此您使用了大量的ajax而不是太多的页面更改。这意味着一旦加载了内容,它将长时间驻留在页面中。

所以拥有社交网络&其他网络服务内容延迟链接而不是大型并行加载应该不是问题。也许它不会出现在前15秒,但如果它在接下来的15分钟内停留在页面上那么它可能不是问题(如果最重要的内容已经存在,用户可能甚至不会注意到装饰性内容是没有的。一个IE6(有时是IE7)提示,在任何地方使用SetTimeouts() js命令来强制重新绘制页面,你会看到可用内容显示得更快。

最后提示,如果您需要对更新的内容进行常规的ajax检查。如果您真的每分钟检查10个内容,那么您将始终遇到并行加载问题和大活动,与初始加载相同的问题,通常您可以使用2个方法来解决该问题,一个是 COMET < / strong> familly长时间运行的HTTP连接(因此您可以改为PUSH数据和/或获得更快的响应,但只能在您的服务器针对那种HTTP流量进行调整)。第二个是为下一次检查添加时间因子,以便第一次检查是在1分钟之后,下一次检查是2分钟,然后是3,15,25等,最后你有一个可能每小时只检查一次。当您检测到用户的某些活动(某些用户交互)时,您可以减少下一次检查延迟。这是因为您可以假设用户只是在他真正对您的页面做某事时才真正在寻找新数据。您将节省一些用户CPU,并且还可以帮助您加载服务器。

答案 1 :(得分:0)

由于Facebook / LinkedId / etc插件,我也有页面加载延迟。

我的解决方案是异步加载第三方JavaScript。 它不适用于每个网络服务/小部件,但适用于其中许多(Facebook“喜欢”按钮,Twitter“推特”按钮等)。

示例:

<div id="tweet">
    <a href="http://twitter.com/share" 
        class="twitter-share-button" 
        data-count="horizontal"
    >Tweet</a>
</div>
<script type="text/javascript">
    $(function() {
        $.getScript('http://platform.twitter.com/widgets.js');
    });
</script>

此代码将在页面(DOM)加载后呈现“推文”按钮。

但是你应该首先检查请求的web服务的JavaScript是否使用document.write()。如果是的话 - 你在这里什么都不做,只能同步加载。