[英]Best practice for getting around limitation on concurrent ajax calls
由于没有发布代码而冒着被烘烤的风险,解决ajax请求的6个并发调用限制的最佳方法是什么?
所以目前我正在使用一个应用程序,在页面加载时最多可以有40个ajax请求。 对于后台,这些请求中的大部分都是针对隐藏在标签后面的各种图形。 有些请求可以由用户触发(例如更新实体名称而不刷新页面)。 这意味着由于对并发请求的限制,用户将无法更改任何内容,直到只有其他5个请求在运行,这是一种不可接受的用户体验。
这可能意味着应用程序结构严重,但大多数加载的东西都不是立即需要的。
无论如何,我看了一下fetch()和webworkers,但找不到有关这些是否有助于解决限制的任何信息。
一种解决方案是将资源放在不同的子域上,但这会使后端API变得不必要地复杂化(这是一个浏览器问题,而不是服务器问题)。
我考虑过这些方法:
这是非常基于意见的。
40个请求并非不合理,但根据您的服务器和站点设置,它可能需要相当长的时间。
通过那么多次调用,我会在initializePage=X
调用中将它们中的一些捆绑在一起。 这确实涉及一些服务器端工作。
Delay requests
不一定是坏的,具体取决于您的预计交付时间。 如果可能的话,您可以在响应进入之前呈现某种动画或“预期结果”,以保持用户受理。 这同样适用于对请求进行Queing
。
如果在服务器上运行大量初始化(如安全检查),重构代码以返回捆绑中的所有内容也可以大大加快您的站点速度。
如果性能仍然是一个问题,您可以查看提供更快结果的连接,例如EventSource或WebSocket 。 这种更快的连接还允许更灵活的链接方法。 例如,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.