Ile jednoczesnych żądań AJAX (XmlHttpRequest) jest dozwolonych w popularnych przeglądarkach?

358

W Firefoksie 3 odpowiedź wynosi 6 na domenę: jak tylko zostanie uruchomiony siódmy XmlHttpRequest (na dowolnej karcie) do tej samej domeny, jest on ustawiany w kolejce, aż jedna z pozostałych 6 zakończy.

Jakie są liczby dla innych głównych przeglądarek?

Czy są też sposoby na obejście tych ograniczeń bez konieczności modyfikowania przez moich użytkowników ustawień przeglądarki? Na przykład, czy istnieją ograniczenia liczby żądań jsonp (które używają wstrzykiwania znaczników skryptu zamiast obiektu XmlHttpRequest)?

Tło: Moi użytkownicy mogą tworzyć XmlHttpRequests ze strony internetowej na serwer, prosząc serwer o uruchomienie poleceń ssh na zdalnych hostach. Jeśli hosty zdalne są wyłączone, polecenie ssh nie powiedzie się przez kilka minut, co ostatecznie uniemożliwi moim użytkownikom wykonywanie dalszych poleceń.

Michael Gundlach
źródło
Biorąc pod uwagę twoją sytuację, jaka jest wykonalność pingowania zdalnego węża, aby sprawdzić, czy jest w górę, czy w dół? To nie odpowie na twoje pytanie, ale może to być lepszy przepływ pracy.
Bob
1
Dzięki, Bob, to jedno z dwóch podejść, które planowałem rozwiązać ten problem - rozważałem wspomnienie o nim w pytaniu, ale zdecydowałem, że to nie na temat. (Innym podejściem jest, aby serwer, który kontroluję, przekroczył limit czasu żądań ssh.)
Michael Gundlach
1
Myślę, że masz dość odpowiedzi ... założenie, że Safari i Chrome obsługują co najmniej 2, jest więcej niż bezpieczne, więc zawsze możesz założyć 2.
Rex M
1
Korzystając z Chrome 2.0.172.28 w systemie Windows Vista mam 6 jednoczesnych połączeń.
Callum
2
Właśnie znalazłem tę stronę stevesouders.com/blog/2008/03/20/..., która zawiera kilka liczb i dyskusję na ten temat.
David Johnstone,

Odpowiedzi:

143

Jednym ze sposobów na zwiększenie liczby jednoczesnych połączeń jest hostowanie obrazów z innej subdomeny. Będą one traktowane jako osobne żądania, każda domena będzie ograniczona do równoczesnego maksimum.

IE6, IE7 - mają limit dwóch. IE8 to 6, jeśli masz łącze szerokopasmowe - 2 (jeśli jest to połączenie dial-up).

Kok
źródło
4
Nie, ograniczenia są nałożone na domenę. Więc możesz technicznie uzyskać FF do 12 połączeń, jeśli oprócz swojej witryny masz subdomenę.
Bob
1
Więc jeśli cię rozumiem, FF ogranicza wszystkie żądania (do jednej domeny) do 6 - nie tylko XmlHttpRequests do jednej domeny. Inne przeglądarki robią to samo z różnymi limitami. Poprawny?
Michael Gundlach
1
O tak, jeśli masz stronę z tysiącem zdjęć, pobierze je w grupach po sześć. Wierzę, że większość innych przeglądarek głównego nurtu działa w ten sam sposób.
Bob
7
Łał. To dobra sztuczka. To wyjaśnia również, dlaczego serwery kafelków dla silników map tworzą wiele fałszywych subdomen (zwykle coś w rodzaju map1.whthing.com, map2.whthing.com, map3.whthing.com) w celu przyspieszenia.
meawoppl
2
@AMember, przeglądarka utrzymuje równolegle maksymalną dozwoloną liczbę jednoczesnych aukcji dozwoloną przez cały czas. Wypróbuj moją odpowiedź poniżej, jeśli chcesz zobaczyć w akcji
Luis Siquot,
103

Wyniki sieciowe w Browserscope dadzą Ci zarówno Połączenia na nazwę hosta, jak i Max Połączenia dla popularnych przeglądarek. Dane są gromadzone poprzez przeprowadzanie testów na użytkownikach „na wolności”, dzięki czemu będą aktualne.

Kevin Hakanson
źródło
3
Niestety nie wygląda to na zdalnie aktualne
Dave Lawrence,
@DaveLawrence Właśnie sprawdziłem, a pełny zestaw danych zawiera Chrome 60 i 61, co jest dość aktualne.
Simon East
24

Dzięki IE6 / IE7 można dostosować liczbę jednoczesnych żądań w rejestrze. Oto jak ustawić go na cztery.

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings]
"MaxConnectionsPerServer"=dword:00000004
"MaxConnectionsPer1_0Server"=dword:00000004
Brianegge
źródło
15
-1. OP powiedział without having my users modify their browser settings. Nie jest to również praktyczne, ponieważ trzeba to zrobić na każdym kliencie.
Razort4x 12.04.13
23
Jest to jednak bardzo przydatna rzecz związana z tym problemem. Być może lepiej byłoby opublikować je w komentarzu niż jako odpowiedź?
JD Smith
7

Właśnie sprawdziłem na www.browserscope.org, a dzięki IE9 i Chrome 24 możesz mieć 6 równoczesnych połączeń z jedną domeną, a nawet 17 z wieloma.

xmorera
źródło
6

Według IE 9 - co się zmieniło? na blogu HttpWatch, IE9 nadal ma limit 2 połączeń w sieci VPN.

Korzystanie z VPN Still Clobbers Wydajność IE 9

Wcześniej informowaliśmy o zmniejszeniu maksymalnej liczby równoczesnych połączeń w IE 8, gdy komputer korzysta z połączenia VPN. Stało się tak, nawet jeśli ruch przeglądarki nie przekroczył tego połączenia.

Niestety na IE 9 wpływają połączenia VPN w ten sam sposób:

Kevin Hakanson
źródło
6

Napisałem jeden tester plików AJAX. Ciesz się !!! Tylko dlatego, że miałem problemy z moim dostawcą hostingu

<?php /*

Author:   Luis Siquot
Purpose:  Check ajax performance and errors
License:  GPL
site5:    Please don't drop json requests (nor delay)!!!!

*/

$r = (int)$_GET['r'];
$w = (int)$_GET['w'];
if($r) { 
   sleep($w);
   echo json_encode($_GET);
   die ();
}  //else
?><head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">

var _settimer;
var _timer;
var _waiting;

$(function(){
  clearTable();
  $('#boton').bind('click', donow);
})

function donow(){
  var w;
  var estim = 0;
  _waiting = $('#total')[0].value * 1;
  clearTable();
  for(var r=1;r<=_waiting;r++){
       w = Math.floor(Math.random()*6)+2;
       estim += w;
       dodebug({r:r, w:w});
       $.ajax({url: '<?php echo $_SERVER['SCRIPT_NAME']; ?>',
               data:    {r:r, w:w},
               dataType: 'json',   // 'html', 
               type: 'GET',
               success: function(CBdata, status) {
                  CBdebug(CBdata);
               }
       });
  }
  doStat(estim);
  timer(estim+10);
}

function doStat(what){
    $('#stat').replaceWith(
       '<table border="0" id="stat"><tr><td>Request Time Sum=<th>'+what+
       '<td>&nbsp;&nbsp;/2=<th>'+Math.ceil(what/2)+
       '<td>&nbsp;&nbsp;/3=<th>'+Math.ceil(what/3)+
       '<td>&nbsp;&nbsp;/4=<th>'+Math.ceil(what/4)+
       '<td>&nbsp;&nbsp;/6=<th>'+Math.ceil(what/6)+
       '<td>&nbsp;&nbsp;/8=<th>'+Math.ceil(what/8)+
       '<td> &nbsp; (seconds)</table>'
    );
}

function timer(what){
  if(what)         {_timer = 0; _settimer = what;}
  if(_waiting==0)  {
    $('#showTimer')[0].innerHTML = 'completed in <b>' + _timer + ' seconds</b> (aprox)';
    return ;
  }
  if(_timer<_settimer){
     $('#showTimer')[0].innerHTML = _timer;
     setTimeout("timer()",1000);
     _timer++;
     return;
  }
  $('#showTimer')[0].innerHTML = '<b>don\'t wait any more!!!</b>';
}


function CBdebug(what){
    _waiting--;
    $('#req'+what.r)[0].innerHTML = 'x';
}


function dodebug(what){
    var tt = '<tr><td>' + what.r + '<td>' + what.w + '<td id=req' + what.r + '>&nbsp;'
    $('#debug').append(tt);
}


function clearTable(){
    $('#debug').replaceWith('<table border="1" id="debug"><tr><td>Request #<td>Wait Time<td>Done</table>');
}


</script>
</head>
<body>
<center>
<input type="button" value="start" id="boton">
<input type="text" value="80" id="total" size="2"> concurrent json requests
<table id="stat"><tr><td>&nbsp;</table>
Elapsed Time: <span id="showTimer"></span>
<table id="debug"></table>
</center>
</body>

Edycja:
r oznacza wiersz i czas oczekiwania.
Kiedy początkowo naciśniesz przycisk Start 80 (lub dowolną inną liczbę) współbieżnego żądania ajax są uruchamiane przez javascript, ale jak wiadomo są one buforowane przez przeglądarkę. Są one również przesyłane do serwera równolegle (ograniczona do pewnej liczby, to jest fakt tego pytania). Tutaj żądania są rozwiązywane po stronie serwera z losowym opóźnieniem (ustalonym przez w). W momencie rozpoczęcia obliczany jest cały czas potrzebny do rozwiązania wszystkich wywołań ajax. Po zakończeniu testu można sprawdzić, czy zajęło to połowę, zajęło trzecie, zajęło ćwierć itd. Całkowitego czasu, odejmując, która była równoległością połączeń do serwera. Nie jest to ani ścisłe, ani precyzyjne, ale miło jest zobaczyć w czasie rzeczywistym, w jaki sposób wykonywane są wywołania ajaxs (widząc przychodzący krzyż). I jest to bardzo prosty samodzielny skrypt pokazujący podstawy ajax.
Oczywiście zakłada to, że po stronie serwera nie wprowadzono żadnego dodatkowego limitu.
Najlepiej używać w połączeniu z panelem sieci firebug (lub odpowiednikiem przeglądarki)

Luis Siquot
źródło
więc potwierdzam, FF3 uruchamia do sześciu równoczesnych próśb
Luis Siquot,
Czy możesz wyjaśnić, co tutaj zrobiłeś? Co to jest rw? Doceniony zostanie wydrukowany ekran analizy wyniku
Royi Namir,
4

Napisałem własny test. przetestowałem kod na stackoverflow, działa dobrze mówi mi, że chrome / FF może zrobić 6

var change = 0;
var simultanius = 0;
var que = 20; // number of tests

Array(que).join(0).split(0).forEach(function(a,i){
    var xhr = new XMLHttpRequest;
    xhr.open("GET", "/?"+i); // cacheBust
    xhr.onreadystatechange = function() {
        if(xhr.readyState == 2){
            change++;
            simultanius = Math.max(simultanius, change);
        }
        if(xhr.readyState == 4){
            change--;
            que--;
            if(!que){
                console.log(simultanius);
            }
        }
    };
    xhr.send();
});

działa w przypadku większości witryn internetowych, które mogą wywoływać zdarzenia zmiany readystate w różnych momentach. (aka: flushing)

Zauważyłem na moim serwerze node.js, że musiałem wydać co najmniej 1025 bajtów, aby wyzwolić zdarzenie / opróżnienie. w przeciwnym razie zdarzenia po prostu wywołałyby wszystkie trzy stany jednocześnie, gdy żądanie jest kompletne, więc oto mój backend:

var app = require('express')();

app.get("/", function(req,res) {
    res.write(Array(1025).join("a"));
    setTimeout(function() {
        res.end("a");
    },500);
});

app.listen(80);

Aktualizacja

Zauważam, że możesz teraz otrzymać nawet 2x żądanie, jeśli korzystasz jednocześnie z xhr i api

var change = 0;
var simultanius = 0;
var que = 30; // number of tests

Array(que).join(0).split(0).forEach(function(a,i){
    fetch("/?b"+i).then(r => {
        change++;
        simultanius = Math.max(simultanius, change);
        return r.text()
    }).then(r => {
        change--;
        que--;
        if(!que){
            console.log(simultanius);
        }
    });
});

Array(que).join(0).split(0).forEach(function(a,i){
    var xhr = new XMLHttpRequest;
    xhr.open("GET", "/?a"+i); // cacheBust
    xhr.onreadystatechange = function() {
        if(xhr.readyState == 2){
            change++;
            simultanius = Math.max(simultanius, change);
        }
        if(xhr.readyState == 4){
            change--;
            que--;
            if(!que){
                document.body.innerHTML = simultanius;
            }
        }
    };
    xhr.send();
});

Nieskończony
źródło
Na moim jest napisane 19, czy jest zepsute?
PauAI,
Firefox Developer Edition 57.0b12 mówi 2.
AnthonyB
0

Uważam, że istnieje maksymalna liczba równoczesnych żądań HTTP wysyłanych przez przeglądarki do tej samej domeny, co odpowiada kolejności od 4 do 8 żądań w zależności od ustawień użytkownika i przeglądarki.

Możesz skonfigurować swoje prośby o przejście do różnych domen, co może, ale nie musi być wykonalne. Chłopaki z Yahoo przeprowadzili wiele badań w tej dziedzinie, o których można przeczytać ( tutaj ). Pamiętaj, że każda nowa domena, którą dodasz, również wymaga wyszukiwania DNS. Chłopaki z YSlow zalecają od 2 do 4 domen, aby osiągnąć dobry kompromis między równoległymi żądaniami a wyszukiwaniem DNS, chociaż skupia się to na czasie ładowania strony, a nie kolejnych żądaniach AJAX.

Czy mogę zapytać, dlaczego chcesz składać tak wiele wniosków? Istnieją dobre powody, dla których przeglądarki ograniczają liczbę żądań do tej samej domeny. Lepiej będzie, jeśli to możliwe, grupowanie wniosków.

cbp
źródło
1
Moje XmlHttpRequests nie mogą przechodzić do różnych domen, jak sugerujesz, z powodu tych samych zasad pochodzenia. (Być może jest to argument przemawiający za użyciem jsonp w celu obejścia tego problemu.) Ta strona to pulpit kontrolny dla wielu komputerów; w ten sposób odradza się żądanie na wykonanie żądane przez użytkownika.
Michael Gundlach,