簡體   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