首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

AJAX 輪詢數據量大導致 Pending 狀態優化方案:WebSocket 替代

     編輯:程式設計疑難解答

問題現象

使用 setTimeout 每 30 秒發起 AJAX 請求,響應數據達幾百 KB,頻繁出現 pending 狀態,數據獲取失敗,客戶端代碼如下:


function getSchedule(date) {
    var request = { ... };
    jQuery.ajax({
        type: 'POST',
        data: request,
        success: function(response) {
            jQuery("#data").html(loadInfo(response.data));
        }
    });
    setTimeout(function() { getSchedule(date); }, 30000);
}

根因分析

  • 請求頻率過高:30 秒一次,若上個請求未完成,新請求並發,瀏覽器連接數限制導致排隊。
  • 數據量大:幾百 KB 響應傳輸耗時,加劇阻塞。
  • 無錯誤重試/取消機制:網絡波動時無超時控制,殘留連接佔用資源。

優化方案對比

方案一:WebSocket 長連接(推薦)

服務端主動推送增量數據,客戶端單連接持久化,完全消除輪詢開銷。


// 客戶端
var ws = new WebSocket("ws://your-server/schedule");
ws.onmessage = function(event) {
    var data = JSON.parse(event.data);
    jQuery("#data").html(loadInfo(data));
};
ws.onclose = function() { /* 重連邏輯 */ };

// 服務端(Spring Boot 示例)
@ServerEndpoint("/schedule")
public class ScheduleWebSocket {
    @OnOpen
    public void onOpen(Session session) { /* 註冊會話 */ }
    
    // 定時任務推送
    @Scheduled(fixedRate = 30000)
    public void pushUpdates() { /* 發送給所有會話 */ }
}

方案二:優化輪詢(不改架構)

  • 增加 timeout 設置(如 10 秒)。
  • 請求完成後再設置下一次定時器(setTimeout 放入 complete 回調),避免並發。
  • 啟用 HTTP 壓縮(Gzip),減小傳輸體積。
  • 引入 If-Modified-Since/ETag 實現條件請求,無變化返回 304。

function getSchedule(date) {
    $.ajax({
        url: '/api/schedule',
        data: {date: date, lastUpdate: lastTimestamp},
        timeout: 10000,
        success: function(resp, status, xhr) {
            lastTimestamp = xhr.getResponseHeader('Last-Modified');
            renderData(resp.data);
        },
        complete: function() {
            setTimeout(() => getSchedule(date), 30000); // 完成後再排程
        }
    });
}

建議選型

實時性要求高、數據頻繁變動 → WebSocket;
數據變動較緩、改動成本敏感 → 優化輪詢。
長遠看,WebSocket 是即時通訊的標準解法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved