今天在對項目做性能分析時發現,js代碼中同時發出的多個異步請求耗時很長,查看服務器處理 時間發現,每個請求的響應都在毫秒級,
但是頁面請求的響應時間卻在1秒左右,百思不得其解,后來仔細測試發現,這個並發的ajax請求雖然是同時進入的服 務器,但是各
自的處理時間卻存在彼此等待的情況,每個請求的時間處理時間都為幾毫秒,但是卻在等待上一個請求的結束才開始處理,
后來查資料發現以下tips:
xmlhttp存在最大並發數,ajax設計應有所斟酌
這次認真的測試了三種瀏覽器(ie/firefox/opera)的xmlhttp並發行為,發現如果用戶同時發出很多xmlhttp 異步請求,那么瀏覽器不是一股腦全把請求發出去,而是存在一個最大並發數。我的機器測試發現,ie和ff里面是2,opera是4。
所以說,在設計一個站點時,讓ajax頁面同時載入數十個xmlhttp請求不是明智的做法。在考慮減少接口耦合的同時,也應該斟酌速度問題。實際上,可以使用某些細化的設計,可以把多種請求綁定到一起發送,從而達到優化的目的。
Ajax並發
Ajax是以異步的方式向服務器提交需求,這就會存在多個ajax請求同時提交,或者迭代提交的情況,這將導致資源競爭(racing),設計較好的 情況下,可以通過disable提交按鈕的緩解此類問題,但一旦出現迭代提交request的情況,就可能出現XMLHttpRequest對象的引用被 覆蓋,但具體會發生什么樣的情況,取決於Ajax的編碼。
Ajax在異步的情況下,並發數並非沒有限制,Wininet 會限制每個服務器的連接數,限制它對單個 HTTP 服務器的同時連接的數量。
如果超過此限制時,請求將阻止,直到完成當前的連接之一。這是設計使然,是與 HTTP 規范和行業標准。例如IE8並發數就限制在2,Firefox
21限制在6。當然IE的限制可以在注冊表中修改,HKEY_LOCAL_MACHINE\SOFTWARE\ Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER。
ersion | HTTP 1.0 server (broadband connection) | HTTP 1.1 server (broadband connection) | HTTP 1.0 server (dial-up connection) |
HTTP 1.1 server (dial-up connection) |
Internet Explorer 7 and earlier | 4 | 2 | 4 | 2 |
Internet Explorer 8 | 6 | 6 | 4 | 2 |
超出上述限制,超出的請求將會被瀏覽器阻塞,直到先前的請求已經完成才會啟動。在這里建立使用隊列來解決這些問題。基本思路,生成XHR對象之后,檢 測當前並發數量是否大於最大請求的上限,若大於上限,則將XHR對象壓入隊列之中,否則就可以直接發送,並且可以繼續增加並發請求數量。請求完成的時候, 進行響應處理,並在結束之時進行並發數量減一操作,接着就可以檢測隊列中是否有等待請求,若有等待請求,就發送給隊首的XHR對象進行請求。