Combien de demandes AJAX (XmlHttpRequest) simultanées sont autorisées dans les navigateurs populaires?

358

Dans Firefox 3, la réponse est 6 par domaine: dès qu'une 7e XmlHttpRequest (sur n'importe quel onglet) vers le même domaine est déclenchée, elle est mise en file d'attente jusqu'à ce que l'un des 6 autres se termine.

Quels sont les chiffres pour les autres principaux navigateurs?

De plus, existe-t-il des moyens de contourner ces limites sans que mes utilisateurs modifient les paramètres de leur navigateur? Par exemple, y a-t-il des limites au nombre de requêtes jsonp (qui utilisent l'injection de balises de script plutôt qu'un objet XmlHttpRequest)?

Contexte: Mes utilisateurs peuvent effectuer des requêtes XmlHttpRequests à partir d'une page Web vers le serveur, en demandant au serveur d'exécuter des commandes ssh sur des hôtes distants. Si les hôtes distants sont en panne, la commande ssh prend quelques minutes pour échouer, empêchant éventuellement mes utilisateurs d'exécuter d'autres commandes.

Michael Gundlach
la source
En pensant à votre situation, quelle est la faisabilité de cingler le tuyau distant pour voir s'il est en haut ou en bas? Cela ne répondra pas à votre question, mais cela pourrait être un meilleur flux de travail.
Bob
1
Merci Bob, c'est l'une des deux approches que j'avais prévues pour résoudre ce problème - j'ai envisagé de le mentionner dans la question mais j'ai décidé que c'était hors sujet. (Une autre approche consiste à faire en sorte que le serveur, que je contrôle, expire les requêtes ssh.)
Michael Gundlach
1
Je pense que vous avez à peu près votre réponse ... il est plus que sûr de supposer que Safari et Chrome prennent en charge au moins 2, vous pouvez donc toujours en supposer 2.
Rex M
1
En utilisant Chrome 2.0.172.28 sur Windows Vista, j'ai obtenu 6 connexions simultanées.
Callum
2
Je viens de trouver cette page stevesouders.com/blog/2008/03/20/… qui donne quelques chiffres supplémentaires et une discussion à ce sujet.
David Johnstone

Réponses:

143

Une astuce que vous pouvez utiliser pour augmenter le nombre de connexions simultanées consiste à héberger vos images à partir d'un sous-domaine différent. Celles-ci seront traitées comme des demandes distinctes, chaque domaine est ce qui sera limité au maximum simultané.

IE6, IE7 - ont une limite de deux. IE8 est 6 si vous avez un haut débit - 2 (s'il s'agit d'un accès commuté).

Bob
la source
4
Non, les limites sont imposées au domaine. Ainsi, vous pourriez techniquement obtenir jusqu'à 12 connexions FF si vous aviez un sous-domaine en plus de votre site.
Bob
1
Donc, si je vous comprends bien, FF limite toutes les demandes (à un seul domaine) à 6 - pas seulement XmlHttpRequests à un seul domaine. Et d'autres navigateurs font la même chose avec des limites différentes. Correct?
Michael Gundlach
1
Ohh oui, si vous avez une page avec mille images, elle les téléchargera par groupes de six. Je pense que la plupart des autres navigateurs traditionnels fonctionnent de la même manière.
Bob
7
Sensationnel. C'est une bonne astuce. Cela explique également pourquoi les serveurs de tuiles pour les moteurs de carte créent un certain nombre de faux sous-domaines (généralement quelque chose comme maps1.wthing.com, maps2.wwhat.com, maps3.wwhat.com) pour accélérer les choses.
meawoppl
2
@AMember, le navigateur conserve en parallèle son nombre maximum d'ajax simultanés autorisé à tout moment. Essayez ma réponse ci-dessous si vous voulez voir en action
Luis Siquot
103

Les résultats du réseau sur Browserscope vous donneront à la fois des connexions par nom d'hôte et des connexions maximales pour les navigateurs populaires. Les données sont collectées en exécutant des tests sur les utilisateurs "dans la nature", afin de rester à jour.

Kevin Hakanson
la source
3
Malheureusement, cela ne semble pas à jour
Dave Lawrence
@DaveLawrence Je viens de vérifier et le jeu de données complet semble contenir Chrome 60 et 61 qui est assez à jour.
Simon East
24

Avec IE6 / IE7, on peut modifier le nombre de demandes simultanées dans le registre. Voici comment le définir sur quatre chacun.

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings]
"MaxConnectionsPerServer"=dword:00000004
"MaxConnectionsPer1_0Server"=dword:00000004
brianegge
la source
15
-1. Dit OP without having my users modify their browser settings. De plus, ce n'est pas pratique car il faudrait le faire sur chaque client.
Razort4x du
23
C'est néanmoins une chose très utile à savoir, liée à ce problème. Peut-être aurait-il été mieux affiché dans un commentaire que comme réponse?
JD Smith
7

Je viens de vérifier avec www.browserscope.org et avec IE9 et Chrome 24, vous pouvez avoir 6 connexions simultanées à un seul domaine, et jusqu'à 17 à plusieurs.

xmorera
la source
6

Selon IE 9 - Qu'est-ce qui a changé? sur le blog HttpWatch, IE9 a toujours une limite de 2 connexions lorsqu'il est sur VPN.

Utilisation d'un VPN Clobbers encore IE 9 Performance

Nous avons précédemment signalé la réduction du nombre maximal de connexions simultanées dans IE 8 lorsque votre PC utilise une connexion VPN. Cela s'est produit même si le trafic du navigateur ne passait pas par cette connexion.

Malheureusement, IE 9 est affecté par les connexions VPN de la même manière:

Kevin Hakanson
la source
6

J'ai écrit un testeur AJAX à fichier unique. Profitez-en!!! Tout simplement parce que j'ai eu des problèmes avec mon hébergeur

<?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>

Edit:
r signifie ligne et w temps d'attente.
Lorsque vous appuyez initialement sur le bouton de démarrage 80 (ou tout autre nombre) de demande ajax simultanée sont lancées par javascript, mais comme on le sait, elles sont spoulées par le navigateur. Ils sont également demandés au serveur en parallèle (limité à un certain nombre, c'est le fait de cette question). Ici, les requêtes sont résolues côté serveur avec un retard aléatoire (établi par w). À l'heure de début, tout le temps nécessaire pour résoudre tous les appels ajax est calculé. Lorsque le test est terminé, vous pouvez voir si cela a pris la moitié, la troisième, le quart, etc. du temps total, en déduisant quel était le parallélisme sur les appels au serveur. Ce n'est pas strict, ni précis, mais c'est agréable de voir en temps réel comment les appels ajaxs sont terminés (voir la croix entrante). Et est un script autonome très simple pour montrer les bases ajax.
Bien sûr, cela suppose que le côté serveur n'introduit aucune limite supplémentaire.
À utiliser de préférence avec le panneau Firebug Net (ou l'équivalent de votre navigateur)

Luis Siquot
la source
donc je confirme, FF3 lance jusqu'à six requêtes simultanées
Luis Siquot
Pouvez-vous expliquer ce que vous avez fait ici? Qu'est-ce que r et w? Un écran d'impression des résultats d'analyse serait très apprécié
Royi Namir
4

A écrit mon propre test. testé le code sur stackoverflow, fonctionne très bien me dit que chrome / FF peut faire 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();
});

cela fonctionne pour la plupart des sites Web qui peuvent déclencher un événement de changement de readystate à différents moments. (aka: rinçage)

J'ai remarqué sur mon serveur node.js que je devais produire au moins 1025 octets pour déclencher l'événement / vidage. sinon, les événements déclencheraient simplement les trois états à la fois lorsque la demande est terminée, voici donc mon 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);

Mise à jour

Je remarque que vous pouvez maintenant avoir jusqu'à 2x requêtes si vous utilisez à la fois xhr et fetch 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();
});

Interminable
la source
Il est écrit 19 sur le mien, est-il cassé?
PauAI
Firefox Developer Edition 57.0b12 dit 2.
AnthonyB
0

Je crois qu'il y a un nombre maximum de demandes http simultanées que les navigateurs feront au même domaine, qui est de l'ordre de 4 à 8 demandes selon les paramètres de l'utilisateur et le navigateur.

Vous pouvez configurer vos demandes pour accéder à différents domaines, ce qui peut ou non être réalisable. Les gars de Yahoo ont fait beaucoup de recherches dans ce domaine, que vous pouvez lire ( ici ). N'oubliez pas que chaque nouveau domaine que vous ajoutez nécessite également une recherche DNS. Les gars de YSlow recommandent entre 2 et 4 domaines pour obtenir un bon compromis entre les demandes parallèles et les recherches DNS, bien que cela se concentre sur le temps de chargement de la page, et non sur les demandes AJAX suivantes.

Puis-je vous demander pourquoi vous souhaitez faire autant de demandes? Il y a de bonnes raisons pour que les navigateurs limitent le nombre de demandes au même domaine. Vous feriez mieux de regrouper les demandes si possible.

cbp
la source
1
Mes XmlHttpRequests ne peuvent pas aller vers différents domaines comme vous le suggérez, en raison de la même politique d'origine. (C'est peut-être un argument pour utiliser jsonp pour contourner ce problème.) Cette page est un tableau de bord de commande et de contrôle pour de nombreux ordinateurs; ainsi une requête est générée par exécution demandée par l'utilisateur.
Michael Gundlach