web-dev-qa-db-ja.com

一般的なブラウザで許可されている同時のAJAX(XmlHttpRequest)リクエストの数

Firefox 3では、答えはドメインごとに6です。同じドメインに対する(任意のタブの)7番目のXmlHttpRequestが実行されるとすぐに、それは他の6つのうちの1つが終わるまで待ち行列に入れられます。

他の主要ブラウザの数字は何ですか?

また、ユーザーにブラウザの設定を変更させずにこれらの制限を回避する方法はありますか?たとえば、jsonpリクエストの数には制限がありますか(XmlHttpRequestオブジェクトではなくスクリプトタグインジェクションを使用する)。

背景:私のユーザーはWebページからサーバーにXmlHttpRequestを送信して、リモートホスト上でsshコマンドを実行するようサーバーに要求することができます。リモートホストがダウンしていると、sshコマンドが失敗するまでに数分かかります。その結果、ユーザーがそれ以上コマンドを実行できなくなります。

348

同時接続数を増やすために使用できるトリックの1つは、別のサブドメインからイメージをホストすることです。これらは別々のリクエストとして扱われます、各ドメインは同時最大に制限されるものです。

IE6、IE7 - 2つの制限があります。あなたがブロードバンドを持っていればIE8は6です - 2(それがダイヤルアップなら)。

139
Bob

Browserscope にあるネットワークの結果から、Connections per HostnameMax Connectionsの両方が一般的なブラウザに表示されます。データは「実際に」ユーザーにテストを実行することによって収集されるので、最新の状態に保たれます。

102
Kevin Hakanson

IE6/IE7では、レジストリ内の同時リクエスト数を微調整できます。これをそれぞれ4つに設定する方法は次のとおりです。

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings]
"MaxConnectionsPerServer"=dword:00000004
"MaxConnectionsPer1_0Server"=dword:00000004
24
brianegge

私は www.browserscope.org でチェックしました、そしてIE9とChrome 24ではあなたは一つのドメインへの6つの同時接続と最大17から複数のものを持つことができます。

7
xmorera

HttpWatchブログの IE 9 - 変更点は? によると、VPNを使用する場合、IE 9の接続数は2つに制限されています。

VPN Still Clobbersの使用IE 9パフォーマンス

お使いのPCがVPN接続を使用している場合、IE 8の最大同時接続数の縮小について以前に報告しました。ブラウザのトラフィックがその接続を経由しなかったとしても、これは起こりました。

残念ながら、IE 9は同様にVPN接続の影響を受けます。

6
Kevin Hakanson

単一のファイルAJAXテスターを書きました。楽しめ!!!ホスティングプロバイダに問題があるからといって

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

編集:
rはrowとwの待ち時間を意味します。
最初にスタートボタン80(またはその他の数)を同時に押すと、javascriptによって起動されますが、知られているように、それらはブラウザによってスプールされます。また、それらはサーバーに並行して要求されます(特定の数に制限されます。これはこの質問の事実です)。ここで要求はランダムな遅延(wによって確立される)でサーバー側で解決されます。開始時に、すべてのAjax呼び出しを解決するのに必要なすべての時間が計算されます。テストが終了したら、合計時間の半分、3分の1、4分の1などの時間がかかっているかどうかを確認し、どれがサーバーへの呼び出しの並列処理であるかを差し引いてください。これは厳密でも厳密でもありませんが、リアルタイムでajax呼び出しがどのように完了するかを見るのはいいことです(入ってくるクロスを見てください)。そしてこれは、Ajaxの基本を示すための非常に単純な自己完結型スクリプトです。
もちろん、これはサーバー側が追加の制限を導入していないことを前提としています。
できればfirebug net panel(またはあなたのブラウザの同等物)と組み合わせて使用​​してください。

6
Luis Siquot

私自身のテストを書きました。 stackoverflowでコードをテストしました、うまく動作しますchrome/FFができることを私に告げます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();
});

それは異なった時にreadystate changeイベントを引き起こすことができるほとんどのウェブサイトのために働きます。 (別名:フラッシング)

私は私のnode.jsサーバーで私はイベント/フラッシュを引き起こすために少なくとも1025バイトを出力しなければならなかったことに気づきます。そうでなければ、イベントはリクエストが完了したときに3つの状態すべてを一度にトリガーするだけなので、これが私のバックエンドです:

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

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

app.listen(80);

更新

Xhrとfetch apiの両方を同時に使用している場合は、最大2倍のリクエストが可能になります。

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();
});
4
Endless

私は、ブラウザが同じドメインに対して同時に行うことができるhttpリクエストの最大数があると信じています。これは、ユーザーの設定とブラウザに応じて、4〜8リクエストのオーダーです。

別のドメインに移動するようにリクエストを設定することもできますが、それは実現可能な場合も不可能な場合もあります。 Yahooの人たちはこの分野でたくさんの調査をしました、それについてあなたは読むことができます( ここ )。新しいドメインを追加するたびにDNSルックアップも必要になります。 YSlowの連中は、並列リクエストとDNSルックアップの妥協点を見つけるために2〜4ドメインを推奨していますが、これはその後のAJAXリクエストではなくページのロード時間に焦点を合わせています。

なぜあなたがそんなに多くの要求をしたいのか私に尋ねることができますか?ブラウザが同じドメインへのリクエスト数を制限するのには、正当な理由があります。可能であれば、リクエストをまとめたほうがよいでしょう。

0
cbp