I programmed an experiment in javascript/jquery extensively using ajax to communicate with the server / execute php scripts on the server.
Now, a friend of mine wants to use the scripts in japan and is running into problems that I haven't encountered before.
For example he has to press submit buttons several times instead of just getting redirected to the next page or he sees placeholder symbols instead of the data that is stored in the mysql database and should have been fetched (and replace the placeholders).
In the last case, the script is quite straightforward. A $.post request is executed in the document ready function, which then executes a function in which the javascript replacements take place.
Now we are kind of lost what could be the cause of it. It seems to work fine on my side.
The server is located in europe and he also had some issues with proxy servers.
Could that be a problem?
Could it be that the $.post commands are just very slow or even time out?
Is there anything that can be done about this to make the scripts run reliably on his side?
I am happy to provide more specific information if needed, however currently I am a little bit lost and don't know what to look for specifically.
Thanks for any help!
edit:
Here is the jquery code for one specific example where we encountered this problem:
function updateContent() {
$.post("php/earnings.php",
{
type: "contribution",
grp : group,
pbnr : PbNr,
multiplier : multiplier
}, processAndShow);
function processAndShow(data) {
// here are just jquery commands updating html elements
}
}
$(document).ready(function() {
updateContent();
});
the earnings.php file contain roughly 150 lines of code with 15 mysql_query requests.
I also had a look at the connection diagnostics in firefox for the earnings.php $.post request:
Connection: "Keep-Alive";
Keep-Alive: "timeout=1, max=96"
has it possibly something to do with the timeout / max settings of the apache server?
Related
So the whole reason I am using AJAX is to make page changes seem smoother. However I have realized that using AJAX is actually slowing down the website significantly. I am using localhost with apache. I am running php on the backend to access a database for various pages.
It's taken up to 5 seconds just to load a single page.
Here is some AJAX:
$(function() {
$(".menu_nav").click(function() {
$.ajax({
type: "GET",
url: "menu.php",
dataType: 'html',
success: function(data) {
var toInsert = $(data).filter(".placeholder");
var style = $(data).filter("#style");
$("#style").replaceWith(style);
$(".placeholder").replaceWith(toInsert);
window.scrollTo(0,0);
}
});
});
});
'menu_nav' and 'home_nav' are both divs with click events attached to them, and on click they are performing a GET request to the server and asking for a div in the .php as well as it's styling sheet. It then will replace the div and style sheet on this page with what it retrieved from the GET request. Where I am having trouble understanding though is why is this taking up to 5 seconds to perform the GET request, whereas without any javascript I am getting minuscule load times, just less "pretty"?
I looked at the timeline and network tabs in the web inspector, and had noticed that every time I perform one of these requests, I get a new file from the server, rather than reading the one I've already got, which makes sense because there might be new data in the page since the last visit, however I don't see a duplicate being added to the list of sources when I am not using AJAX. For example:
Whereas without AJAX, there is only one. This makes sense since I am initiating a GET request to the server, but the same is happening when you click a link without AJAX.
Regardless, I still don't understand what is making it so slow as opposed to not using JavaScript. I understand it is doing more in addition to just a GET request, but is filtering and replacing text after a response really what is causing this issue?
Side question: This is outside the scope of this question, but in regards to AJAX, when I perform a request to the server, is the PHP within the file still executing before it gives me the HTML? So on pages where a user must have certain permissions, will the PHP that catches that still be ran?
EDIT: I am hosting a MySQL database through a free subscription to a cloud hosting service. This issue occurs when I access my website through both localhost, and when accessing the website that way deployed via the free cloud hosting service, though it is way slower when I use the cloud service. I am also using various resources from the MAMP (MacOS Apache, MySQL, PHP; If you're on windows and interested, WAMP is also available fore free) installation.
I'm not sure what is causing your slowness issues, but you could try doing some profiling to narrow down the issue. My guess is that while changing your code to use ajax, you also introduced or revealed some bug that's causing this slowness issue.
Is there an issue with the javascript? You can place console.time() and console.timeEnd() in different places to see how long a chunk of javascript takes to execute. (e.g. at the start and end of your ajax callback). Based on what you posted, this is likely not the issue, but you can always double check.
Is it PHP that's running slow? You can use similar profiling functions in PHP to make sure it's not hanging on something.
Are there network issues? You could, for example, log the timestamp of when javascript sent the request and when PHP received it, and vice versa. (this should work OK on localhost, but in other environments you have to be careful of clocks being out of sync)
There's a lot that could be going wrong here, so its hard to give a more specific answer, but hopefully that gives you some tools to help you start looking.
As for your side question: you are correct - PHP will start sending the HTML while it continues to execute. For example:
<div>
<?php someLongBlockingFunction(); ?>
</div>
<div> will get sent to the browser, then PHP will stall on the long-running-function before it finally sends out the ending </div>. The browser will piece together the chunks, and your event listener won't get called until PHP has finished sending the entire file.
I'm developing a web application and use jQuery to make asynchronous HTTP requests to my API. I have a detail view where you can see a lot of information of a specific object stored in the database. Because there is a lot of information and data that is linked to other objects, I make different calls to my API to gather different information for my views.
In the 'detail view' I have some kind of widgets that show the requested information. For that, I make about 5-7 HTTP GET requests to my API. When using the debugger (both Safari and Firefox), I can see that some requests are blocking other requests and the page takes a lot of time until everything is loaded and shown to the user.
I make a request like this:
$.get("api/api.php?object=myobject&endpoint=someendpoint", function(data) {
// data is JSON formatted
$("#my-widget input").val(data["name"]);
});
And another one e.g. like this:
$.get("api/api.php?object=anotherobject&endpoint=anotherendpoint", function(data) {
// data is JSON formatted
$("#other-widget input").val(data["somekey"]);
});
If the first request takes a little longer to finish, it blocks the second request until the callback function of the first request finished. But why? I thought that those calls are asynchronous and non-blocking.
I want to build a fast web application for a company where the requests are only made inside the local network, so a request should only take about 10-50ms (or even less). But the page takes about 10 seconds to show up with all information.
Am I doing something wrong? Or is there a JavaScript framework that can be used for exactly this problem? Any help is appreciated!
EDIT: As you can see in the screenshot, the requests have to wait some seconds, and if the request is fired, it takes a few seconds until a response comes back.
If I call the URL directly in my browser or do a GET request using curl it is a lot faster.
EDIT2: Thanks #CBroe! The session file write lock was the problem. As long as the session file is locked, no other script can run until the previous script finished. I just called session_write_close() immediately after session_start() and it runs a lot faster now.
Attention: Use session_write_close() only if you don't need to write to the $_SESSION array. Reading is possible after that, but writing not. (See this topic for further details: https://stackoverflow.com/a/50368260/1427878)
I have created a website for a friend. Because he wished to have a music player continue to play music through page loads, I decided to load content into the page via ajax (facilitated by jQuery). It works fine, it falls back nicely when there is no javascript, and the back/forward buttons are working great, but it's dreadfully slow on the server.
A couple points:
The initial page load is fairly quick. The Chrome developer console tells me that "index.php" loads in about 2.5 seconds. I have it set up so that query string params dictate which page is loaded, and this time frame is approximately accurate for them all. For the homepage, there is 8.4KB of data loaded.
When I load the content in via an ajax request, no matter the size of the data downloaded, it takes approximately 20 seconds. The smallest amount of data that is loaded in this way is about 500 bytes. There is obviously a mismatch here.
So Chrome tells me that the vast majority of the time spent is "waiting" which I take to mean that the server is dealing with the request. So, that can only mean, I guess, that either my code is taking a long time, or something screwy is going on with the server. I don't think it's my code, because it's fairly minimal:
$file = "";
if (isset($_GET['page'])) {
$file = $_GET['page'];
} else if (isset($_POST['page'])) {
$file = $_POST['page'];
} else {
$file = "home";
}
$file = 'content/' . $file . '.php';
if (file_exists($file)) {
include_once($file);
} else {
include_once('content/404.php');
}
This is in a content_loader.php file which my javascript (in this scenario) sends a GET request to along with a "page" parameter. HTML markup is returned and put into a DIV on the page.
I'm using the jQuery .get() shorthand function, so I don't imagine I could be messing anything up there, and I'm confident it's not a Javascript problem because the delay is in waiting for the data from the server. And again, even when the data is very small, it takes about 20 seconds.
I currently believe it's a problem with the server, but I don't understand why a request made through javascript would be so much slower than a request made the traditional way through the browser. As an additional note, some of the content pages do connect to a MySQL database, but some do not. It doesn't seem to matter what the page requires for processing or how much data it consists of, it takes right around 20 seconds.
I'm at a loss... does anyone know of anything that might explain this? Also, I apologize if this is not the correct place for such a question, none of the other venues seemed particularly well suited for the question either.
As I mentioned in my comment, a definite possibility could be reverse DNS lookups. I've had this problem before and I bet it's the source of your slow requests. There are certain Apache config directives you need to watch out for in both regular apache and vhost configs as well as .htaccess. Here are some links that should hopefully help:
http://www.tablix.org/~avian/blog/archives/2011/04/reverse_dns_lookups_and_apache/
http://betabug.ch/blogs/ch-athens/933
To find more resources just Google something like "apache slow reverse dns".
A very little explanation
In a reverse DNS lookup an attempt is made to resolve an IP address to a hostname. Most of the time with services like Apache, SSH and MySQL this is unnecessary and it's a bad idea as it only serves to slow down requests/connections. It's good to look for configuration settings for your different services and disable reverse DNS lookups if they aren't needed.
In Apache there are certain configuration settings that cause a reverse lookup to occur. Things like HostnameLookups and allow/deny rules specifying domains instead of IP addresses. See the links above for more info.
As you suggested in your comment, the PHP script is executing quickly once it finally runs. The time is spent waiting on Apache - most likely to do a reverse DNS lookup, and failing. You know the problem isn't with your code, it's with the other services involved in the request.
Hope this helps!
Imagine we have a server side application that generates streaming content full of JavaScript commands. The easiest way for me to show the example application is to use Python/Flask, however you can perform it using any language just flushing the output after each iteration. So, for a sample server side application:
from time import sleep from flask import Response
#app.route('/stream', methods=['POST']) def stream():
def generate():
for i in range(10):
sleep(1)
yield 'console.log("Iteration: %d");\n' % i
return Response(generate(), mimetype='application/javascript')
which returns (during 10 seconds with 1 second pauses) this kind of output:
console.log("Iteration: 0");
console.log("Iteration: 1");
console.log("Iteration: 2");
...
console.log("Iteration: 9");
I need to create a "parent" HTML/JavaScript page which handles and executes these commands on-the-fly, i.e. not waiting until all 10 iterations will be loaded. Also, it should be able to serve POST requests to the mentioned server side application.
Here are the options which I have tried.
I tested jQuery Ajax method with different options but it still
needs full generated output to execute all commands at once.
The other idea was to use iframe. It works fine but in order to
use it I need to rephrase my output from console.log("Iteration:
0"); to <script language="JavaScript">console.log("Iteration:
0");</script> with content type text/html; and also to simulate
POST form submission to the target iframe.
I have read about WebSockets. However, since this technology is not
absolutely supported at the moment, and my application should be
able to work with on-the-fly content already now, I refused to deal
with it.
Another very important thing: the output should be a stream, since server side application works with a long lasting process; so make setTimeout(function() { $.ajax(...); }, 1000); is not the solution.
To summarize, I have tried several options but simple iframe is the only solution which really works at the moment. Otherwise, most probably I am missing something. Any thoughts and constructive ideas are very much appreciated.
Thank you in advance!
long-Polling and comet are options, but these are hacks. The Iframe method you mentioned isn't terrible, but has some state issues if you need to recover the connection.
I would encourage you to reconsider web sockets. There is a lovely shim available on github which uses flash (which has had socket support for some time now) as a fall back. You can write client side code as if web sockets exist, and the shim adds it to browsers that don't support it. Great!
I'm just wondering..is it possible to receive multiple responses from a single ajax call?
I'm thinking purely for aesthetic purposes to update the status on the client side.
I have a single ajax method that's called on form submit
$.ajax({
url: 'ajax-process.php',
data: data,
dataType: 'json',
type: 'post',
success: function (j) {
}
});
I can only get one response from the server-side. Is it possible to retrieve intermittent statuses? Such as:
Default (first): Creating account
Next: Sending email confirmation
Next: Done
Thanks for your help! :)
From a single ajax call, I don't think it is possible.
What you could do is check frequently where the process is (it's what is used for the upload bars in gmail for example). You do a first ajax request to launch the process, and then a series of ajax request to ask the server how he is doing. When the server answers "I'm done", you're good to go, and until that you can make the server respond and say the current state.
There is something called comet which you can set up to "push" requests to client, however it is probably way more than what you are wanting to invest in, time-wise.
You can open up a steady stream from the server, so that it continues to output, however I'm not sure how client-side script can handle these as individual "messages". Think about it like a server that outputs some info to the browser, does more work, outputs some more to the browser, does more work, etc. This shows up more or less in real time to the browser as printed text. It is one long response, but it is still one response. I think ajax only handles a response once it finished being sent, but maybe someone else will know more than me on the topic.
But you couldn't have the server output several individual responses without reloading itself, at least not with PHP, because once you start outputting the response, the response has begun and you can't chop that up without finishing the response, which happens when the script is done executing.
Your best bet is with the steady stream, but again, I'm not sure how ajax handles getting responses in chunks.
Quick Update
Based on the notes for this plugin:
[http://plugins.jquery.com/project/ajax-http-stream]
things don't look promising. Specifically:
Apparently the trend is to disallow access to the xmlhttprequest.responseText before the request is complete (stupid imo). Sorry there's nothing I can do to fix this
Thus, not only can you not get what you want in one request, you probably can't get it multiple requests, unless you want to break up the actual server-side process into several parts, and only have it continue to the next step when an ajax function triggers it.
Another option would be to have your script write it's status at specific points to another file on the server, call it "status.xml" or "status.txt". Have your first ajax function initialize the process, and have a second ajax function that queries this status file and outputs that to the user.
It is possible, but it has more to do with your backend script. As Anthony mentioned there is a tech called comet. Another term I've heard is called "Long polling". The idea is that you delay the time in which your php(insert language of choice) script finished processing.
In php you can do something like this:
while($response !== 'I'm done'){
sleep(1);
}else{
return $some_value;
exit();
}
This code stops your script from completely finishing. sleep(1) allows the script to stop and lets the server rest for 1 millisecond, before it loops back through. You can adjust the sleep time based on your needs. In php the amount of time the script sleeps is not counted agains your server timeout time.
You'll obviously need to make more checks for you code. You'll probably also want to allow for an abort script call. Something like sending a get request to kill the backend script. Maybe on the javascript unload event.
In the tests that I've done. I made the initial ajax call, and when the value was returned, I made another ajax call, that way your back end script wont time out.
I've only played around with this on my local server, so i'm not sure how real world this is, but it works.