Loading the same file via ajax 12 times at once - javascript

I hope this makes sense...
I have a page that loads the same external file 1-12 times depending on the usage. The larger load times takes up to a full minute to load the page so I'm trying to load each file via ajax, but using a loop to load the files completely hangs the server.
Here's the code I'm using so far:
function getSchedule(startday,scheduleID,scheduleView){
$.ajax({
type: 'POST',
url: siteURL+'/includes/schedule-'+scheduleView,
data: {startday:startday,scheduleID:scheduleID},
success: function(data){
$('.scheduleHolder'+scheduleID).html(data).removeClass('loading');
}
});
}
var loadSchedules = [];
var startday = $('#the_start_day').text();
var totalSchedules = $('.scheduleHolder').length;
var i = 0;
$('.scheduleHolder').each(function(){
var currentHolder = $(this);
var scheduleView = currentHolder.attr('rel');
var scheduleID = currentHolder.attr('id');
loadSchedules.push(getSchedule(startday,scheduleID,scheduleView));
if (totalSchedules==i) {
$.when.apply($, loadSchedules);
}
i++;
});
Each file should only take 2-5 seconds to load when it's loading individually, so I was really hoping the total load time could go from 60 seconds to 10 or so.
So, my question is how can I load the same file multiple times and at the same time without killing the server? Does that make sense?

I believe you need to use synchronous requests, this hopefully helps:
jQuery: Performing synchronous AJAX requests
(the wording is a bit misleading, read here: Asynchronous and Synchronous Terms )
but I can't vouch what will happen to your server with the 12 simultaneous requests - if the other end is written well, nothing.

Related

What alternativ is best for interval page reloading?

I am pretty lazy, I've made a code that is fetching data from the database and then reloading a page on the index every second if something is changing, so it's visible without needing to refresh the page.
What alternative is faster?
function getLowPlayers() {
var httpd;
if (window.XMLHttpRequest) {
httpd = new XMLHttpRequest();
} else if (window.ActiveXObject) {
httpd = new ActiveXObject("Microsoft.XMLHTTP");
}
httpd.onreadystatechange=function()
{
if (httpd.readyState==4 && httpd.status==200)
{
document.getElementById("lowplayers").innerHTML= httpd.responseText;
setTimeout(getLowPlayers, 1000);
}
}
httpd.open("GET", "includes/ajax.php?noCache=" + Math.random(), true);
httpd.send();
}
or this one:
function ajaxCall() {
$.ajax({
url: "ajax.php",
success: (function (result) {
var res = $.parseJSON(result);
var str1 = "<center><img src='https://steamcommunity-a.akamaihd.net/economy/image/";
var str3 = " ' height='60' width='70'/></br>";
var mes = [];
var div = [];
})
})
};
I know that it is a silly solution to do like this, I could setup a socket.io server, but I think it's too much of work.
I understand that with many visitors, the ajax.php file would send way to many queries per second, is that healthy for the database? Or is it fine with todays internet speed and hosting services?
Which one is faster? Or do you guys have any better solution?
The two codes are more or less the same, the first is written in javascript vainlla, and the second is in JQuery and therefore is shorter and simpler.
If I had to decide, I would choose the second code since it is easier to read and maintain.
Regarding the performance between those 2 codes is practically the same, although if there were many connections the option to use ajax would not be very correct since each server request occupies "X" memory that if we are talking about large numbers would mean that the page was will load slowly because of the waiting queues.
So the best idea as you say is to confiure socket.io and try to update the page with calls from the server to customers.

Loading CSVs Periodically using AJAX

I'm trying to load multiple CSV files each 5seconds for updating some displays in Google Maps API v3, but only loads one or two, never all the files.
Here is the code:
setInterval(function() {
checkLaneStatus();
initMap();
}, 2000);
function checkLaneStatus(){
laneStatus('landing_lane.csv',landing_lane);
laneStatus('landing_curve.csv',landing_curve);
laneStatus('arrival_lane_1.csv',arrival_lane_1);
laneStatus('arrival_lane_2.csv',arrival_lane_2);
laneStatus('arrival_lane_3.csv',arrival_lane_3);
laneStatus('arrival_lane_4.csv',arrival_lane_4);
laneStatus('t1.csv',terminal1);
laneStatus('t2.csv',terminal2);
laneStatus('t3.csv',terminal3);
laneStatus('t4.csv',terminal4);
laneStatus('departure_lane_1.csv',departure_lane_1);
laneStatus('departure_lane_2.csv',departure_lane_2);
laneStatus('departure_lane_3.csv',departure_lane_3);
laneStatus('departure_lane_4.csv',departure_lane_4);
laneStatus('departure_curve.csv',departure_curve);
laneStatus('departure_lane.csv',departure_lane);
}
function laneStatus(file,lane){
var temp = lane;
$.ajax({
type: "GET",
url: file,
dataType: "text",
success: function(data) {processData(data);}
});
function processData(allText) {
console.log(allText);
var allTextLines = allText.split(/\r\n|\n/);
var entries = allTextLines[0].split(',');
if(entries[2] != -1){
temp.setOptions({strokeColor: colorRed, fillColor: colorRed});
}
}
}
CSV file example (id,name,status): If the status is -1 means that the lane is free any other number means that is busy.
1,'Departure Lane 1',-1
The supposed behavior is: Loading same csv and update display colors, so should check all csv for detect changes. But it only loads one csv each interval, so only that "lane" is updated.
laneStatus function receives the location of the csv that are located in the root (same folder of the index.html where the code is executed). "lane" argument is a google.maps.Rectangle object.
I guess that I explained well, would appreciate any reply!
Thanks!
You are likely hitting your browsers max simultaneous request limit. Because you cannot control your end-users browser config what about implementing a simple queue that is just a first in first out array. Add each request to the queue, and have a second interval that creates one of those requests every 500 milliseconds or so until the queue is empty.
If you are in control of the data could you combine some of the files with one more column for what lane it corresponds to? Or even write a simple middleware layer that combines them, it would speed up the page quite a bit as it only has to open the one connection.
I also like using web sockets (socket.io) if you are going to pull data that often as it keeps a persistent connection across requests.

Loading TXT files before displaying them with ajax [duplicate]

This question already has answers here:
Sequencing ajax requests
(10 answers)
Closed 7 years ago.
I'm working on a small text game in js, and the easiest way I found to have save text is to use text files. I can order them in different folders, they really light and they're easily identifiable and editable in case I need to make changes.
I'm loading them using ajax
$.ajax({
url: 'text/example.txt',
success: function(text){
document.getElementById("main").innerHTML = document.getElementById("main").innerHTML + text;
}
});
As it was suggested to me in another thread.
And honestly, so far it's been working pretty well, in single-cases scenarios. When only one TXT file needs to be displayed there are literally no problems. But, unfortunately in cases where a lot of different files need to be displayed in a correct order (let's say around 10 different files), the text gets messed up and loads out of order. I'm going to suppose this is because it just can't fetch the txt file fast enough.
So at this point I'm really not too sure what to do.
Is there a way to get my script to wait before printing the next piece of text before displaying one that still hasn't loaded?
Maybe a way to load all the txt files when the site is accessed?
My knowledge is pretty limited so I'm really not sure how this could be fixed.
Tried searching google and stackoverflow, none of the threads I found are helping me, perhaps because I'm really not an expert.
You can achieve with callback, the following way will call ajax one by one after they finish:
//setup an array of AJAX url
var ajaxes = [{ url : 'text/example.txt'}, { url : 'text/example1.txt'}],
current = 0;
//declare your function to run AJAX requests
function do_ajax() {
//check to make sure there are more requests to make
if (current < ajaxes.length) {
//make the AJAX request with the given data from the `ajaxes` array of objects
$.ajax({
url : ajaxes[current].url,
success : function (text) {
document.getElementById("main").innerHTML = document.getElementById("main").innerHTML + text;
//increment the `current` counter and recursively call this function again
current++;
do_ajax();
}
});
}
}
//run the AJAX function for the first time when you want
do_ajax();

Bytes received and bytes total of images via Javascript/jQuery

I'm working on a Javascript/jQuery powered image preloader, and have hit a bit of a snag. While as of currently it provides the progress based on loaded_images / total_images, this is not very accurate given a page could have a thousand 1kB images, and a single 1MB image.
I'm looking for a way to incorporate filesize into the progress calculations. Now, I've looked into some (cross browser compatible) tricks at capturing the filesize of a given image, and it seems that Ajax requests for Content-Length were the most reliable (in terms of accuracy) like so:
var imageSizeTotal = 0;
var ajaxReqest = $.ajax({
type: 'HEAD',
url: 'path/to/image',
success: function(message){
imageSizeTotal += parseInt(ajaxRequest.getResponseHeader('Content-Length'));
}
});
Now, I find this method to be quite useful, as I can provide a status message of Initializing while the necessary requests are taking place. However my issue now is two-fold:
Is there any way possible to capture the bytes loaded of a given image object, perhaps using setInterval() to periodically check? Otherwise, I'm sort of back at the issue of the progress indicator hanging on large files.
How can I force the actual progress calculator, etc., portion of the script to wait until the necessary Ajax requests are completed (displaying Initializing or whatever), so it can go ahead with the loading?
Also, here's the script I currently use, which again, calculates progress based on the number of images, regardless of filesize or bytes received.
var preloaderTotal = 0;
var preloaderLoaded = 0;
var preloaderCurrent = null;
$('#preloaderCurtain')
.bind('preloaderStart', function(){
$(this)
.show();
$('*')
.filter(function(e){
if($(this).css('background-image') != 'none'){
preloaderTotal++;
return true;
}
})
.each(function(index){
preloaderCurrent = new Image();
preloaderCurrent.src = $(this).css('background-image').slice(5, -2);
preloaderCurrent.onload = function(e){
preloaderLoaded++;
if(preloaderLoaded == preloaderTotal - 1){
$('#preloaderCurtain')
.trigger('preloaderComplete')
}
$('#preloaderCurtain')
.trigger('preloaderProgress')
};
});
})
.bind('preloaderComplete', function(){
$(this)
.fadeOut(500)
startAnimation();
})
.bind('preloaderProgress', function(e){
$('#preloaderProgress')
.css('opacity', 0.25 + (preloaderLoaded / preloaderTotal))
.text(Math.floor((preloaderLoaded / preloaderTotal) * 100) + '%');
})
.trigger('preloaderStart');
Hopefully I'll be able to turn this into a plugin, once I work the bugs out of it.
It looks like a similar question was asked and answered here:
XmlHttpRequest.responseText while loading (readyState==3) in Chrome
and here:
Comet Jetty/Tomcat, having some browser issues with Firefox and Chrome
Basically - .responseText.length for Firefox and iPhone, .responseBody.length for IE, WebSockets for Chrome.
The second thread suggests bayeux/dojo encapsulate all this for you into a higher-level API so you don't have to write it yourself.

$(window).unload wait for AJAX call to finish before leaving a webpage [duplicate]

This question already has answers here:
JavaScript, browsers, window close - send an AJAX request or run a script on window closing
(9 answers)
Closed 6 years ago.
Basically, once a user leaves a webpage in my application, I need to call a PHP script with AJAX, which will insert a time spent on the webpage to the database and then leave the page.
It is important to wait for the AJAX request to finish because webpages in my application are not accessible to users unless they have spent a certain time on a previous page (let's say two minutes).
Here is my jquery code:
$(document).ready(function() {
var teid = TEID;
var startTime = new Date().getTime();
$(window).unload(function() {
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
$.ajax({
type: 'POST',
url: '/clientarea/utils/record-time',
data: 'teid=' + teid + '&t=' + t
});
});
});
How should I change it so it will wait for the AJAX request to end before leaving the webpage?
EDIT:
Or it might be better (easier) to just let the AJAX request be repeated every minute or so. Is that possible?
Well, you can set async: false on your AJAX call to make the browser wait for the request to finish before doing anything else, but note that this will 'hang' the browser for the duration of the request.
$.ajax({
type: 'POST',
async: false,
url: '/clientarea/utils/record-time',
data: 'teid=' + teid + '&t=' + t
});
From the manual:
By default, all requests are sent asynchronous (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.
⚠ WARNING: This answer was posted in 2010 and is now outdated - the XHR specification highlights the following statement:
Synchronous XMLHttpRequest outside of workers is in the process of being removed from the web platform as it has detrimental effects to the end user’s experience. (This is a long process that takes many years.) Developers must not pass false for the async argument when current global object is a Window object. User agents are strongly encouraged to warn about such usage in developer tools and may experiment with throwing an "InvalidAccessError" DOMException when it occurs.
DevTools in Chrome has recently started warning about it, so this change (which has been coming for some years) could be imminent.
The best solution is to use navigator.sendBeacon. It is brand new functionality which is starting to get implemented in new releases of browsers. The function is available in browsers newer than Chrome 39 and Firefox 31. It is not supported by Internet Explorer and Safari at the time of writing. To make sure your request gets send in the browsers that don't support the new functionality yet, you can use this solution:
var navigator.sendBeacon = navigator.sendBeacon || function (url, data) {
var client = new XMLHttpRequest();
client.open("POST", url, false); // third parameter indicates sync xhr
client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
client.send(data);
};
Hope this helps!
How about setting a cookie in the unload handler? The server should see it on the subsequent requests.
<script>
$(window).unload(function(){document.cookie='left_on='+(new Date())})
</script>
for me, yours is not a good idea for the browser to wait before closing...
simply because what if I really want to close it?...
if a page bother a user, it's not good...
my suggestion is, in the page, you wait for 2 minutes (if 2 minutes is the requirements), then send an ajax that the user has done his 2 minutes...
you can then check it on the server side if one has his 2 minutes or not...
It is a bad idea to try and hijack your users' browser, since it will give them a bad feeling and send them away.
If for some reason you want not to produce a new page until the user has spent a minimum time on the previous one, the best thing to do is to pilot server side, i.e. redirecting to the current page until the requested time has passed.
You don't even need to make ajax calls, just store in the session the timestamp of when the page was served, and don't show the following page until a certain amount of time has passed.
Be sure to tell the users they have to wait for a new page to be ready, maybe with a simple javascript countdown.
If you want the user to actually have the page active for a certain amount of time (i.e. not to switch to another tab/window waiting for the two minutes to elapse), well, I cannot propose an effective solution.
use onbeforeunload:
$(document).ready(function(){
window.onbeforeunload = function(){
// $.ajax stuff here
return false;
}
});
This will at least bring the user a messagebox which asks him if he wants to close the current window/tab.
I think it would be much better to use a polling technique as you suggest, though it will cause some load on the web server.
$(document).ready(function() {
var teid = TEID;
var startTime = new Date().getTime();
var ajaxFunc = function() {
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
$.ajax({
type: 'POST',
url: '/clientarea/utils/record-time',
data: 'teid=' + teid + '&t=' + t
});
};
setInterval(ajaxFunc, 60000);
})
You'll be glad when you can use websockets :)
The jQuery.ajax() method has the option async. If you set it to false the call will block until the response comes back (or it timed out). I'm pretty shure, that calling this, will yause the browser to weit in the unload handler.
Side note: You can't rely on this to work. If the browser gives the user the option to cancel the unload handlers (which some browsers do after a while of waiting), the "time spend on site" will never be updated. You could add a timer to the site, which periodically calls a script on the server and which updates the time. You won't have an accurate value, but in your case, this isn't needed.
If you only need to know if the user was X seconds on the page You could simply set a timeout in the onload handler (using setTimeout(function, ms)) which makes a call if the user has spend the needed time. So there would be no need for a unload handler.

Categories