I try to send ajax requests and do GUI animation in the same time(about 150 requests in a second). It's fine when I doing the first time, and the animation becomes laggy even I refresh the page or restart the browser.
Therefore I tried removing everything in ajax callback, but the browser still acts very laggy while waiting responses. I also tried jquery $.get, and set async to 'true', but the problem still exists.
However, if I change ajax to websocket, this problem is solved. Is that means, ajax requests send by js affect performance? I want to figure this out, thanks!
code :
var i = 0;
var f = setInterval(function(){
// url is an array
addItem(url[i]);
i++;
if(i >=url.length) clearInterval(f);
},33);
// send ajax requests
function addItem(url){
var xml = new XMLHttpRequest();
xml.open('GET',url,true);
xml.send();
xml.onreadystatechange = function(){
if(xml.readyState == 4 && xml.status==200){
// do nothing
}
}
}
150 requests/second seems like bad design. You need to group your requests and send fewer. The animation makes it worse. I believe there is no valid explanation to have this many requests. Yes, you can switch to WebSocket, but make sure your communication does not duplicate messages and does not send multiple messages which could be sent as a single message.
Related
** JAVASCRIPT question **
I'm using regularly ajax via XMLHttpRequest. But in 1 case, I need 1 ajax call per seconds....
but long term wise and with growing number of simultaneous users, it could bloat easily...
I'm reading stuff about webRTC data channel and it seems interesting and promissing.
Here my working AJAX function as an example of how easy and there is a few lines of codes to communicate from the browser to the server and vice-versa
function xhrAJAX ( divID , param2 ) {
// random value for each call to avoid cache
var pcache = (Math.floor(Math.random() * 100000000) + 1);
// parameters
var params = "divID="+encodeURIComponent(divID)+"¶m2="+encodeURIComponent(param2);
// setup XMLHttpRequest with pcache
var xhr = new XMLHttpRequest();
xhr.open("POST", "/file.php?pcache="+pcache, true);
// setup headers
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// prepare onready scripts
xhr.onreadystatechange = function(e) { if (xhr.readyState == 4) { $("#"+divID).html(e.currentTarget.responseText) ; } }
// send the ajax call
xhr.send(params);
}
How can I "transpose" or "convert" this ajax workflow into a webRTC data channel ? in order to avoid to setup a setInterval 1000...
Note: I mean how to replace the javascript portion of the code. PHP here is only to illustrate, I don't want to do a webRTC via PHP...
Is there a simple few lines of code way to push/receive data like this ajax function ?
the answer I'm looking for is more like a simple function to push and receive
(once the connection with STUN, ICE, TURN is established and working...)
If I need to include a javascript library like jquery or the equivalent for webRTC, I'm welcoming good and simple solution.
*** The main goal is this kind of scenario :
I have a webapp : users in desktop and users within webview in Android and IOS
right now I have this workflow => ajax every 3 seconds to "tell" the main database that the user is still active and using the browser (or the app)
But I'd like to replace with this kind : when the user uses the browser => do a webrtc data chata in background between the browser and the server
While reading on the web I think that webRTC is a better solution than websocket.
** I did a bit of search and found peerjs....
https://github.com/jmcker/Peer-to-Peer-Cue-System/blob/main/send.html
I'll do some testing, but in the meantime, if someone can trow ideas, it could be fun.
Cheers
I have a web page that has a too much content and javascript. When the page loads it makes multiple requests using Ajax and XMLHttp to load data. Is there a way to hook up all these requests and direct them to a different server.
For example the webpage fetches data from www.apple.com/data and www.mango.com/data after it is loaded. Is is possible to insert a script somewhere in the webpage which automatically changes any request made to www.orange.com/data.
Waiting for answer. Thanks
You can add a global handler to the ajaxSend event, the event will be triggered right before the ajax request being sent out. So you can check the request uri, apply some filtering logic, and then redirect the request by abort the original and resend it.
Below is an example
$(document).ajaxSend(function(e, xhr, opt) {
if (opt.url.indexOf("www.apple.com") !== -1) {
// abort the request
xhr.abort();
// change the uri to www.orange.com
opt.url = opt.url.replace("www.apple.com", "www.orange.com");
$.ajax(opt);
}
});
Ok. So I followed Anthony C's answer and it did actually work. But the problem with his solution is that it only works with Ajax requests not XMLHttpRequests (I am not sure why, I am a beginner at this topic.) However digging on his idea of creating a hook I came across a similar post here How to get the URL of a xmlhttp request (AJAX). The code provided a way to fetch the requested URL for each request. So by a little tweak to the code I managed to come up with this:-
XMLHttpRequest.prototype.open = (function(open) {
return function(method,url,async) {
var uri=getLocation(url);// use get location function to convert requested url string into readable url
if(uri.hostname!="orange.com"){
url="https://orange.com" + url;
}
open.apply(this,arguments);
};
})(XMLHttpRequest.prototype.open);
var getLocation = function(href) {
var l = document.createElement("a");
l.href = href;
return l;
};
This code at top of the page allows me to change the host name of all XMLHttpRequests that are not directed towards orange.com. Though I am sure there are better ways to write this code as well but since I am not an expert over javascript this will suffice my need for the time.
I'm doing a project with arduino in which I send different requests to the server (the arduino board) with the method XMLHttprequest and Get from a webpage. Except one of the request the others are used only for sending orders to the server, so I don't expect for an XML response. The other one is a request sent in intervals of 5 seconds for getting different values from the server.
The problem arrives with this last one. Actually the webpage sends the request (because I see it on the browser console and the arduino serial monitor) every 5 seconds, but it doesn't get anything, just the headers of the answer confirming the response but nothing about the XML file. Surprisingly, when I write a normal request using the get method in the browser I get instantly the XML file with the values, and It happens all the time I do that.
I'm going to write the javascript code I'm using on the webpage
setInterval(function tiempo()
{
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (this.readyState == 4) {
if (this.status == 200) {
if (this.responseXML != null) {
// extract XML data from XML file (containing switch states and analog value)
document.getElementById("input1").innerHTML = this.responseXML.getElementsByTagName('dato')[0].childNodes[0].nodeValue;
document.getElementById("input2").innerHTML = this.responseXML.getElementsByTagName('dato')[1].childNodes[0].nodeValue;
document.getElementById("input3").innerHTML = this.responseXML.getElementsByTagName('dato')[2].childNodes[0].nodeValue;
document.getElementById("input4").innerHTML = this.responseXML.getElementsByTagName('dato')[3].childNodes[0].nodeValue;
document.getElementById("input5").innerHTML = this.responseXML.getElementsByTagName('dato')[4].childNodes[0].nodeValue;
document.getElementById("input6").innerHTML = this.responseXML.getElementsByTagName('dato')[5].childNodes[0].nodeValue;
document.getElementById("input7").innerHTML = this.responseXML.getElementsByTagName('dato')[6].childNodes[0].nodeValue;
}
}
}
}
request.open("GET", "URL" + Math.random(), true);
request.send(null);
}
, 5000);
On the other hand, if I only write in the browser URL, I get the XML without any problem.
One las thing I have to say is that right now I'm using a webpage stored in my computer but before I was using a webpage stored in the arduino (on an SD card) and loaded also through the internet from arduino. The same code in that case worked perfectly. The reason because I changed It is because arduino ethernet is not too fast and It took so much time. With the webpage stored in my computer It goes faster because It only needs to send the orders.
Thanks!!
Finally, I figured out the problem. It is the browser. For any reason only Internet Explorer works correctly with the webpage. Neither firefox nor other web browsers got the xml file. I don't know the reason but I would like to find it.
If someone knows something about I would be glad of trying to resolve the problem.
Thanks!!
I have an issue, mainly with IE.
I need to be able to handle n queries one after another. But If I simply call my function below in a for loop IE does some strange things (like loading only so many of the calls).
If I use an alert box it proves that the function gets all of the calls, and surprisingly IT WORKS!
My guess is that IE needs more time than other browsers, and the alert box does just that.
Here is my code:
var Ajax = function(all) {
this.xhr = new XMLHTTPREQUEST(); // Function returns xhr object/ activeX
this.uri = function(queries) { // Takes an object and formats query string
var qs = "", i = 0, len = size(queries);
for (value in queries) {
qs += value + "=" + queries[value];
if (++i <= len) { qs += "&"; }
}
return qs;
};
xhr.onreadystatechange = function() { // called when content is ready
if (this.readyState === 4) {
if (this.status === 200) {
all.success(this.responseText, all.params);
}
this.abort();
}
};
this.post = function() { // POST
xhr.open("POST", all.where, true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send(uri(all.queries));
};
this.get = function() { // GET
xhr.open("GET", all.where + "?" + uri(all.queries), true);
xhr.send();
};
if (this instanceof Ajax) {
return this.Ajax;
} else {
return new Ajax(all);
}
};
This function works perfectly for a single request, but how can I get it to work when called so many times within a loop?
I think the problem might be related to the 2 concurrent connections limit that most web browsers implement.
It looks like the latency of your web service to respond is making your AJAX requests overlap, which in turn is exceeding the 2 concurrent connections limit.
You may want to check out these articles regarding this limitation:
The Dreaded 2 Connection Limit
The Two HTTP Connection Limit Issue
Circumventing browser connection limits for fun and profit
This limit is also suggested in the HTTP spec: section 8.14 last paragraph, which is probably the main reason why most browsers impose it.
To work around this problem, you may want to consider the option of relaunching your AJAX request ONLY after a successful response from the previous AJAX call. This will prevent the overlap from happening. Consider the following example:
function autoUpdate () {
var ajaxConnection = new Ext.data.Connection();
ajaxConnection.request({
method: 'GET',
url: '/web-service/',
success: function (response) {
// Add your logic here for a successful AJAX response.
// ...
// ...
// Relaunch the autoUpdate() function in 100ms. (Could be less or more)
setTimeout(autoUpdate, 100);
}
}
}
This example uses ExtJS, but you could very easily use just XMLHttpRequest.
Given that the limit to a single domain is 2 concurrent connections in most browsers, it doesn't confer any speed advantage launching more than 2 concurrent requests. Launch 2 requests, and dequeue and launch another each time one completes.
I'd suggest throttling your requests so you only have a few (4?) outstanding at any given time. You're probably seeing the result of multiple requests being queued and timing out before your code can handle them all. Just a gess though. We have an ajax library that has built-in throttling and queues the requests so we only have 4 outstanding at any one time and don't see any problems. We routinely q lots per page.
Your code looks like it's put together using the constructor pattern. Are you invoking it with the new operator like var foo = new Ajax(...) in your calling code? Or are you just calling it directly like var foo = Ajax(...) ?
If the latter, you're likely overwriting state on your later calls. It looks like it's designed to be called to create an object, on which the get/post methods are called. This could be your problem if you're "calling it within a loop" as you say.
I have a page with a dropdown. The onchange event calls a Javascript function (below) that includes an Ajax block that retrieves data and populates a TEXTAREA. On the surface, everything works.
I can select any item in the list with no problems. However, if I select an item that has previously been selected, the Ajax call appears to hang. It looks like maybe some weird caching issue or something. If I close the browser and reload the page, all items work again until I re-select.
I've tested for the readyState and status properties when it's hanging, but I get nothing. Am I missing something?
The page is a client project behind authentication so I can't post a URL, but here's the Ajax code. This is in a PHP page, but there's no PHP script related to this.
function getText( id ) {
var txt = document.getElementById( "MyText" );
txt.disabled = "disabled";
txt.innerText = "";
txt.className = "busy";
var oRequest = zXmlHttp.createRequest();
oRequest.open( "get", "get_text.php?id=" + id, true );
oRequest.send( null );
oRequest.onreadystatechange = function() {
if( oRequest.readyState == 4 ) {
if( oRequest.status == 200 ) {
txt.innerText = oRequest.responseText;
} else {
txt.innerText = oRequest.status + ": " + oRequest.statusText;
}
txt.disabled = "";
txt.className = "";
oRequest = null;
}
}}
Edit: The code block seems a little quirky; it won't let me include the final } unless it's on the same line as the previous.
You're setting the onreadystatechange function after you're sending the request. If it takes a long time (ie if it goes to the server), this will probably work, since there will be a delay before it tries to call the callback.
If the page is cached, though, the browser is probably trying to call onreadystatechange immediately in the send method. Move your assignment to onreadystatechange to before the open/send code.
HI,
The caching is due to the same url thats being called repeatedly. If you change the URl dynamically then this issue can be rsolved. Something like by adding a querystring with the current time with the request ( or any random renerated number ) you can change the url without affecting the result
I would guess that you are running into a caching issue. I have noticed that Internet Explorer is more aggressive at caching ajax calls than Firefox is. One way to be sure of what is happening is to use Fiddler2. This application monitors your web traffic, and you would be able to see if the browser is making a request or not, and what cache headers are coming back on the responses that you do get.
You can download fiddler2 from http://www.fiddlertool.com/fiddler/