admin管理员组

文章数量:1393629

I have a page that is executing around 200 ajax requests using jquery.load but it is behaving in a very un-ajax way because the browser is frozen while the results are fetched.

By freezing I mean losing control of the browser, not able to scroll it up and down even. Then the results all display at once when it has finished all requests, but I know it is actually fetching the results 6 at a time (browser controlled "same host" policy) from watching the access log of the target server.

Though the jquery.load mands are built using a "foreach" loop they are already written to the source of the page when the user loads it (so for all intents and purposes they could all be hand written individually), so its not like the page is waiting for the loop to finish. The last "symptom" is that even if it is only 30 requests instead, the issue is just the same.

So it's odd to me and I am looking for ideas of what could cause this and how it could be worked around. It's definitely confusing to the end user especially as it could take 90-100 seconds until all the responses are back and the user regains control of the browser.

One small update:

I have very similar code running in another webapp that does around 20 requests simultaneously without issue. The difference is that instead of fetching a page, it is ssh'ing to the server and reading/updating a file on the file system via a script. I would have thought that would actually have a little more overhead but it has none of these issues.

And as I have said - even 20 requests causes the same issue with the code in question... so I am tempted to think its perhaps curl related... though its pure speculation.

The Bigger update Now with infinitely more Code!!!

The fuller background to app is this. We run a cluster of some of the highest trafficked WebSphere AppServers in the world, which are running our Commerce applications. The intensity of the traffic means that if we simply let traffic on to an appserver before the JVM is warmed up, they crash! So we hit a few key pages before allowing traffic on, as this prepiles all the major servlets, proportions the JVM, and populates some of the servlet caches. Then the traffic can e onto the server with no issues and they run great.

We had a version of the app written in CGI which worked but was so slow due to being synchronous. We are talking about 10 minutes on some clusters to run. Due to being synchronous requests, only one thread on the appserver and one jdbc connection was being used.

So what the new webapp does is use a template of these key pages, to bine with a bunch of market definitions (country code, language code, catalog id's etc) to produce a list of all those URL's that need to be hit. By hitting them all in an asynchronous way it not only runs faster (now taking only 90 seconds), it also does a better job of proportioning the JVM, uses up to 30 threads and opens the JDBC pool to its full number of connections. Thus it's REALLY in a production-like state by the time we let traffic on. So I am very pleased with results, but this browser freeze is annoying me from a purely cosmetic and puzzle-solving point of view.

So now some code, the user simply selects an appserver, the app decides which cluster it is from, and displays the list of puted URL's it will hit. At this point the page is a table of 'Markets x Urls' with each cell having a unique id that the jquery uses to put the right result in the right cell (as we can't guarantee the order in which the results e back - nor do we want to as that takes us back into synchronous territory again.

So at the point at which the user is ready to click Go, the table is written and the jQuery mands prepared. On clicking go the jquery script is executed and URL's are hit and return a HTTP status code for each so we know they were successful.

The JQ part generated looks like (shortened to just a few markets)

$("a#submit").click(function(event) {
    alert(" booya ");
    $("#sesv-1").load("psurl.php?server=servera.domain&url=/se/sv");
    $("#sesv-2").load("psurl.php?server=servera.domain&url=/se/sv/catalog/productsaz/");
    $("#sesv-3").load("psurl.php?server=servera.domain&url=/se/sv/catalog/products/12345678");
    $("#sesv-4").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?storeId=14&productId=103406&StoreNumber=099&langId=-13&ddkey=http:StockSearch");
    $("#sesv-5").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=14&langId=-11&StoreNumber=011");
    $("#atde-1").load("psurl.php?server=servera.domain&url=/at/de");
    $("#atde-2").load("psurl.php?server=servera.domain&url=/at/de/catalog/productsaz/");
    $("#atde-3").load("psurl.php?server=servera.domain&url=/at/de/catalog/products/12345678");
    $("#atde-4").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?storeId=1&productId=103406&StoreNumber=114&langId=-99&ddkey=http:StockSearch");
    $("#atde-5").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=1&langId=-21&StoreNumber=273");
    $("#benl-1").load("psurl.php?server=servera.domain&url=/be/nl");
    $("#benl-2").load("psurl.php?server=servera.domain&url=/be/nl/catalog/productsaz/");
    $("#benl-3").load("psurl.php?server=servera.domain&url=/be/nl/catalog/products/12345678");
    $("#benl-4").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?storeId=18&productId=103406&StoreNumber=412&langId=-44&ddkey=http:StockSearch");
    $("#benl-5").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=18&langId=-23&StoreNumber=482");
    $("#befr-1").load("psurl.php?server=servera.domain&url=/be/fr");
    $("#befr-2").load("psurl.php?server=servera.domain&url=/be/fr/catalog/productsaz/");
    $("#befr-3").load("psurl.php?server=servera.domain&url=/be/fr/catalog/products/12345678");
    $("#befr-4").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?storeId=130&productId=103406&StoreNumber=048&langId=-73&ddkey=http:StockSearch");
    $("#befr-5").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=130&langId=-24&StoreNumber=482");
    $("#caen-1").load("psurl.php?server=servera.domain&url=/ca/en");
    $("#caen-2").load("psurl.php?server=servera.domain&url=/ca/en/catalog/productsaz/");
    $("#caen-3").load("psurl.php?server=servera.domain&url=/ca/en/catalog/products/12345678");
    $("#caen-4").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?storeId=30&productId=103406&StoreNumber=006&langId=-11&ddkey=http:StockSearch");
    $("#caen-5").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=30&langId=-15&StoreNumber=216");
    $("#cafr-1").load("psurl.php?server=servera.domain&url=/ca/fr");
    $("#cafr-2").load("psurl.php?server=servera.domain&url=/ca/fr/catalog/productsaz/");
    $("#cafr-3").load("psurl.php?server=servera.domain&url=/ca/fr/catalog/products/12345678");
    $("#cafr-4").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?storeId=33&productId=103406&StoreNumber=124&langId=-09&ddkey=http:StockSearch");
    $("#cafr-5").load("psurl.php?server=servera.domain&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=33&langId=-16&StoreNumber=216")
    });
});

The PS URL is simply a curl request function that responds with 404, 200, 500 etc which is then used to populate the relevant cell.

function getPage( $url ) {
$options = array(
    CURLOPT_URL             => $url,
    CURLOPT_RETURNTRANSFER => true,                 // return web page
    CURLOPT_HEADER         => true,                 // return headers
    CURLOPT_FOLLOWLOCATION => true,                 // follow redirects
    CURLOPT_ENCODING       => "",                   // handle all encodings
    CURLOPT_USERAGENT      => "pre-surf",           // who am i
    CURLOPT_AUTOREFERER    => true,                 // set referer on redirect
    CURLOPT_CONNECTTIMEOUT => 120,                  // timeout on connect
    CURLOPT_TIMEOUT        => 120,                  // timeout on response
    CURLOPT_MAXREDIRS      => 10,                   // stop after 10 redirects
    CURLOPT_POST            => 0,                   // i am not sending post data
    CURLOPT_SSL_VERIFYHOST => 0,                    // don't verify ssl
    CURLOPT_SSL_VERIFYPEER => FALSE,                //
);

$ch      = curl_init();
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
$err     = curl_errno($ch);
$errmsg  = curl_error($ch) ;
$header  = curl_getinfo($ch);
curl_close($ch);

//  $header['errno']   = $err;
//  $header['errmsg']  = $errmsg;
//  $header['content'] = $content;
return $header['http_status_code'];
}

I have a page that is executing around 200 ajax requests using jquery.load but it is behaving in a very un-ajax way because the browser is frozen while the results are fetched.

By freezing I mean losing control of the browser, not able to scroll it up and down even. Then the results all display at once when it has finished all requests, but I know it is actually fetching the results 6 at a time (browser controlled "same host" policy) from watching the access log of the target server.

Though the jquery.load mands are built using a "foreach" loop they are already written to the source of the page when the user loads it (so for all intents and purposes they could all be hand written individually), so its not like the page is waiting for the loop to finish. The last "symptom" is that even if it is only 30 requests instead, the issue is just the same.

So it's odd to me and I am looking for ideas of what could cause this and how it could be worked around. It's definitely confusing to the end user especially as it could take 90-100 seconds until all the responses are back and the user regains control of the browser.

One small update:

I have very similar code running in another webapp that does around 20 requests simultaneously without issue. The difference is that instead of fetching a page, it is ssh'ing to the server and reading/updating a file on the file system via a script. I would have thought that would actually have a little more overhead but it has none of these issues.

And as I have said - even 20 requests causes the same issue with the code in question... so I am tempted to think its perhaps curl related... though its pure speculation.

The Bigger update Now with infinitely more Code!!!

The fuller background to app is this. We run a cluster of some of the highest trafficked WebSphere AppServers in the world, which are running our Commerce applications. The intensity of the traffic means that if we simply let traffic on to an appserver before the JVM is warmed up, they crash! So we hit a few key pages before allowing traffic on, as this prepiles all the major servlets, proportions the JVM, and populates some of the servlet caches. Then the traffic can e onto the server with no issues and they run great.

We had a version of the app written in CGI which worked but was so slow due to being synchronous. We are talking about 10 minutes on some clusters to run. Due to being synchronous requests, only one thread on the appserver and one jdbc connection was being used.

So what the new webapp does is use a template of these key pages, to bine with a bunch of market definitions (country code, language code, catalog id's etc) to produce a list of all those URL's that need to be hit. By hitting them all in an asynchronous way it not only runs faster (now taking only 90 seconds), it also does a better job of proportioning the JVM, uses up to 30 threads and opens the JDBC pool to its full number of connections. Thus it's REALLY in a production-like state by the time we let traffic on. So I am very pleased with results, but this browser freeze is annoying me from a purely cosmetic and puzzle-solving point of view.

So now some code, the user simply selects an appserver, the app decides which cluster it is from, and displays the list of puted URL's it will hit. At this point the page is a table of 'Markets x Urls' with each cell having a unique id that the jquery uses to put the right result in the right cell (as we can't guarantee the order in which the results e back - nor do we want to as that takes us back into synchronous territory again.

So at the point at which the user is ready to click Go, the table is written and the jQuery mands prepared. On clicking go the jquery script is executed and URL's are hit and return a HTTP status code for each so we know they were successful.

The JQ part generated looks like (shortened to just a few markets)

$("a#submit").click(function(event) {
    alert(" booya ");
    $("#sesv-1").load("psurl.php?server=servera.domain.&url=/se/sv");
    $("#sesv-2").load("psurl.php?server=servera.domain.&url=/se/sv/catalog/productsaz/");
    $("#sesv-3").load("psurl.php?server=servera.domain.&url=/se/sv/catalog/products/12345678");
    $("#sesv-4").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?storeId=14&productId=103406&StoreNumber=099&langId=-13&ddkey=http:StockSearch");
    $("#sesv-5").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=14&langId=-11&StoreNumber=011");
    $("#atde-1").load("psurl.php?server=servera.domain.&url=/at/de");
    $("#atde-2").load("psurl.php?server=servera.domain.&url=/at/de/catalog/productsaz/");
    $("#atde-3").load("psurl.php?server=servera.domain.&url=/at/de/catalog/products/12345678");
    $("#atde-4").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?storeId=1&productId=103406&StoreNumber=114&langId=-99&ddkey=http:StockSearch");
    $("#atde-5").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=1&langId=-21&StoreNumber=273");
    $("#benl-1").load("psurl.php?server=servera.domain.&url=/be/nl");
    $("#benl-2").load("psurl.php?server=servera.domain.&url=/be/nl/catalog/productsaz/");
    $("#benl-3").load("psurl.php?server=servera.domain.&url=/be/nl/catalog/products/12345678");
    $("#benl-4").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?storeId=18&productId=103406&StoreNumber=412&langId=-44&ddkey=http:StockSearch");
    $("#benl-5").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=18&langId=-23&StoreNumber=482");
    $("#befr-1").load("psurl.php?server=servera.domain.&url=/be/fr");
    $("#befr-2").load("psurl.php?server=servera.domain.&url=/be/fr/catalog/productsaz/");
    $("#befr-3").load("psurl.php?server=servera.domain.&url=/be/fr/catalog/products/12345678");
    $("#befr-4").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?storeId=130&productId=103406&StoreNumber=048&langId=-73&ddkey=http:StockSearch");
    $("#befr-5").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=130&langId=-24&StoreNumber=482");
    $("#caen-1").load("psurl.php?server=servera.domain.&url=/ca/en");
    $("#caen-2").load("psurl.php?server=servera.domain.&url=/ca/en/catalog/productsaz/");
    $("#caen-3").load("psurl.php?server=servera.domain.&url=/ca/en/catalog/products/12345678");
    $("#caen-4").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?storeId=30&productId=103406&StoreNumber=006&langId=-11&ddkey=http:StockSearch");
    $("#caen-5").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=30&langId=-15&StoreNumber=216");
    $("#cafr-1").load("psurl.php?server=servera.domain.&url=/ca/fr");
    $("#cafr-2").load("psurl.php?server=servera.domain.&url=/ca/fr/catalog/productsaz/");
    $("#cafr-3").load("psurl.php?server=servera.domain.&url=/ca/fr/catalog/products/12345678");
    $("#cafr-4").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?storeId=33&productId=103406&StoreNumber=124&langId=-09&ddkey=http:StockSearch");
    $("#cafr-5").load("psurl.php?server=servera.domain.&url=/webapp/wcs/stores/servlet/StockSearch?query=testProd&storeId=33&langId=-16&StoreNumber=216")
    });
});

The PS URL is simply a curl request function that responds with 404, 200, 500 etc which is then used to populate the relevant cell.

function getPage( $url ) {
$options = array(
    CURLOPT_URL             => $url,
    CURLOPT_RETURNTRANSFER => true,                 // return web page
    CURLOPT_HEADER         => true,                 // return headers
    CURLOPT_FOLLOWLOCATION => true,                 // follow redirects
    CURLOPT_ENCODING       => "",                   // handle all encodings
    CURLOPT_USERAGENT      => "pre-surf",           // who am i
    CURLOPT_AUTOREFERER    => true,                 // set referer on redirect
    CURLOPT_CONNECTTIMEOUT => 120,                  // timeout on connect
    CURLOPT_TIMEOUT        => 120,                  // timeout on response
    CURLOPT_MAXREDIRS      => 10,                   // stop after 10 redirects
    CURLOPT_POST            => 0,                   // i am not sending post data
    CURLOPT_SSL_VERIFYHOST => 0,                    // don't verify ssl
    CURLOPT_SSL_VERIFYPEER => FALSE,                //
);

$ch      = curl_init();
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
$err     = curl_errno($ch);
$errmsg  = curl_error($ch) ;
$header  = curl_getinfo($ch);
curl_close($ch);

//  $header['errno']   = $err;
//  $header['errmsg']  = $errmsg;
//  $header['content'] = $content;
return $header['http_status_code'];
}
Share Improve this question edited Feb 23, 2012 at 8:48 Seer asked Feb 22, 2012 at 15:38 SeerSeer 5541 gold badge9 silver badges21 bronze badges 19
  • 15 "200 ajax requests" That's why. – BoltClock Commented Feb 22, 2012 at 15:40
  • 5 200 ajax requests is 200 http requests...like opening 200 tabs simultaneously in your browser...no wonder it gets slow – Damien Pirsy Commented Feb 22, 2012 at 15:41
  • 3 Without code - can't really help. Are these 200 requests simultaneous? Even if they aren't it sounds like a heck of a lot. For starters - enable Firebug / Developer console to view the network activity – cloakedninjas Commented Feb 22, 2012 at 15:41
  • 5 There's something wrong with the core design of the page that fires 200 ajax requests for single page access. Also, are you using synchronous or asynchronous transfer? You could provide some code before further advices are given. – N.B. Commented Feb 22, 2012 at 15:44
  • 6 The browser tab analogy isn't really applicable. There's a lot of overhead that goes with a tab (memory allocation, potentially a new process/thread). There's also a lot of difference between pulling down a piece of JSON from the interwebs and loading, deciphering and rendering a plete web page. However, 200 AJAX requests is still a lot for one page (not arguing that) -- it's just not really even close to 200 tabs. – Chris Pratt Commented Feb 22, 2012 at 16:01
 |  Show 14 more ments

1 Answer 1

Reset to default 4

The problem here is not the Ajax requests, the problem is each one of those requests is updating the DOM. The browser redraw is what is causing the browser to lock up.

You need to find a better solution that does not write to the DOM so often.

本文标签: javascriptwhy does the browser freeze when executing many ajax requestsStack Overflow