繁体   English   中英

绕过并发ajax调用限制的最佳实践

[英]Best practice for getting around limitation on concurrent ajax calls

由于没有发布代码而冒着被烘烤的风险,解决ajax请求的6个并发调用限制的最佳方法是什么?

所以目前我正在使用一个应用程序,在页面加载时最多可以有40个ajax请求。 对于后台,这些请求中的大部分都是针对隐藏在标签后面的各种图形。 有些请求可以由用户触发(例如更新实体名称而不刷新页面)。 这意味着由于对并发请求的限制,用户将无法更改任何内容,直到只有其他5个请求在运行,这是一种不可接受的用户体验。

这可能意味着应用程序结构严重,但大多数加载的东西都不是立即需要的。

无论如何,我看了一下fetch()和webworkers,但找不到有关这些是否有助于解决限制的任何信息。

一种解决方案是将资源放在不同的子域上,但这会使后端API变得不必要地复杂化(这是一个浏览器问题,而不是服务器问题)。

我考虑过这些方法:

  • 延迟请求直到用户主动需要它们(IMO这是一个糟糕的用户体验,因为他们将不得不等待很多,这很烦人)
  • 创建一个排队系统,为用户发起的请求留下一个开放点(我不知道如何实现这个,但它应该是可行的)
  • 重构API,以便每个请求返回更多数据(这又是一个后端解决方案,感觉有点脏和unRE​​STful。而且它不一定会改善加载时间)
  • 链接调用,例如使用多个异步AJAX调用最佳实践 (但是考虑到在不相关的端点上有不可预测的调用次数,所以我认为这不是那么实用)
  • webworkers? (再次,不确定这是否有用,因为这用于多线程js)
  • 取()? (我无法找到有关这是否受到相同限制的信息)

这是非常基于意见的。

40个请求并非不合理,但根据您的服务器和站点设置,它可能需要相当长的时间。

通过那么多次调用,我会在initializePage=X调用中将它们中的一些捆绑在一起。 这确实涉及一些服务器端工作。

Delay requests不一定是坏的,具体取决于您的预计交付时间。 如果可能的话,您可以在响应进入之前呈现某种动画或“预期结果”,以保持用户受理。 这同样适用于对请求进行Queing

如果在服务器上运行大量初始化(如安全检查),重构代码以返回捆绑中的所有内容也可以大大加快您的站点速度。

如果性能仍然是一个问题,您可以查看提供更快结果的连接,例如EventSourceWebSocket 这种更快的连接还允许更灵活的链接方法。 例如,EventSource支持事件,因此您可以在单个捆绑请求上设置多个事件,并在服务器返回数据时触发它们。

Web工作者不是答案,因为这里的问题是连接速度和并发连接限制。

我认为我们不能直接回答这个问题。 您提到的一些解决方案是可行的,但根据工作量的不同而不同。 如果您愿意调整体系结构,可以考虑一种GraphQL方法,它可以为您包装捆绑。 我还会说你可以维护REST但是有一个特殊的代理服务可以为你捆绑数据。 我还要说,不要让RESTfullness决定或强迫你如何发展。

此外,延迟请求直到用户需要它似乎是我的合适选择。 这是我们为什么拥有“首选”CSS样式和无限滚动的基础。 现在首先加载所需的东西,并推迟那些在需要时可能并不重要的东西。

如果从一个线程调用这些请求,AJAX调用的并发性就会出现。 如果WebWorker与AJAX一起使用,那么根本没有问题,因为在一个不在主线程中的线程中,每个webworker实例都会被隔离。

我会称之为JaxWeb,我将在下周推送一个git repo,你可能会发现它可以找到纯粹的JS代码来处理它。 现在正在测试,但是它确实解决了这个问题。

例:

在JaxWeb.js中添加以下代码

onmessage = function (e) {
    var JaxWeb = function (e) {
        return {
            requestChannel: {},
            get_csrf_token: function () {
                return this._csrf_token;
            },
            set_csrf_token: function (_csrf_token = null) {
                this._csrf_token = _csrf_token;
            },
            prepare: (function ( e ) {
                this.requestChannel = new XMLHttpRequest();
                this.requestChannel.onreadystatechange = function () {
                    if (this.readyState == 4 && this.status == 200) {
                        postMessage(JSON.parse(this.responseText));
                    }
                };
                this.requestChannel.open(e.data.method, e.data.callname, true);
                this.requestChannel.setRequestHeader("X-CSRF-TOKEN", e.data.token);
                var postData = '';
                if (e.data.data)
                    postData = JSON.stringify(e.data.data);
                this.requestChannel.send(postData);
            })(e)
        }
    };
    return JaxWeb(e);
}

用法:

jaxWebGetServerResponse = function () {
    var wk2 = new Worker('path_to_jaxweb_js/JaxWeb.js');

    wk2.postMessage({
        "callname": '<url end point>',
        "method": '<your http method>',
        "data": ''
    });

    wk2.onmessage = function (serverResponse) {
        //
        //process results
        //with data that is received from server
    }
};



//Invoke the function 
jaxWebGetServerResponse();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM