jquery fetch php data is slow. How to make it fast? - php

As the title describe, the speed of jquery display data is 1 to 2 seconds slower than pure php. Demo at http://plekz.com/test-slow3.php . How to make jquery display data as fast as pure php?
Codes :
<div id="jqryd">
</div>
<script src="javascripts/jquery-1.5.js" type="text/javascript" language="javascript"></script>
<script type="text/javascript">
var jqryd = $('#jqryd');
jQuery.get("sale-show-month2.php", function(data) {
jqryd.html(data);
});
</script>
<?php
$sql = "SELECT payment_date, SUM(price) FROM sale WHERE seller_id=? && Year(payment_date)=? GROUP BY Month(payment_date) DESC"; //this is loged-in user.
$q = $conn->prepare($sql);
$result = $q->execute(array($user_id, $selected_year));
if(!$result){
die("Error Select user table query : ". implode(" : ", $q->errorInfo())); //if don't use implode, output of errorInfo() will be "Array".
}
while($r = $q->fetch(PDO::FETCH_ASSOC)){
$price_db2 = $r['SUM(price)'];
$payment_date_db = $r['payment_date'];
$payment_month_db = date("F", strtotime($payment_date_db));
$payment_month_db2 = date("m", strtotime($payment_date_db));
echo "This is pure php : " . $payment_month_db . " - " . $money_currency . $price_db2 ."<br>";
}
?>

Analyzing the traffic in your site example, I see that, other than result, in your sale-show-month2.php page you return even the jquery javascript. This slow down a lot the whole page: for some reason the network tracer see a querystring in the call like http://plekz.com/javascripts/jquery-1.5.js?_=1337691808625, that doesn't allow the cache to be used.
Simply avoid to return the link to jquery will improve performance.
Even after that you'll see jquery loaded data to come later, but this is due to the fact that the get method is called afeter the first page is loaded. You can see it very clearly with firebug or other tool (chrome and IE has their own).

With regards to the amount of data transfered between server and client I would always just transfer the minimum data required (probably using Plain text / XML or JSON depending on the data) and use the most efficient method to append it to the DOM
No matter how big the data is using the best (in your case fastest) method for appending to the DOM .. check out this jsperf for an indicator which method is fastest
And you will see that using the inbuild DOM creation methods are always faster, for example
var li = document.createElement('li');
li.innerHTML = i;
li.setAttribute('title', 'Element number ' + i);
li.setAttribute('class', 'list-item');
container.appendChild(li);
So in your case I would pass the data as JSON and then loop the nodes and append as required. If there is a lot of data returned then i would paginate the data - or show some initial data then add a "Show more" function that retrieved the next portion of data to be displayed.
With regards to the backend - I would ensure that my query was optimised and was using the correct indexes.

Your question doesn't really make sense. Check the network transfers with firebug or chrome - you'll see you spend about the same time waiting for data in both scenarios. However, after receiving the php'generated data the page takes ages to download jquery - and only then can it request the new data.
The only noteworthy thing is that it takes half a second to connect to your server with jquery - this lag will always be present if the connection is bad. With server-side generated data you'll get it once, with ajax you'll get it twice.
So in your scenario, you cannot speed up the fetch - unless you switch servers to something with proper throughput and proper response times.

While there are some ways to optimise the result, the answer to your question
How to make jquery display data as fast as pure php?
is: It is impossible.
Your Javascript will not be able to load anything into the DOM, until it is parsed and ready. This implies that the "pure PHP" data is already loaded, as it is delivered by the server as part of the main page.
It is only then, when the browser has to do another request to the server, taking another round-trip time, in order to get the AJAX version. So: no matter how good your server and your JS are, the AJAX version will never be as fast as the server-side version.
Note: This applies only for your setup with both version competing. Of course it could make sense to speed up the initial delivery of the HTML page by not using PHP and a database request, then loading some stuff later with AJAX.

Related

Images refreshes every second when fetched by AJAX causing flickering and blinking

So I was making a comment system for my blogging cms project. All i want to achieve is to fetch comments every second from another php file (ex- comment.php) which is fetching data from MySql table, and show it in a div which is-
<div class="results" id="result"></div>
I was able to do it successfully, the text comments load well but image comments (comments having images in it) blinks every second.
probably due to AJAX refreshing the complete div every second.
I would really appreciate if someone can help me figure out how to stop this flickering.
my JavaScript code is-
<script>
function refresh_div() {
jQuery.ajax({
url:'comment.php',
type:'POST',
success:function(results) {
jQuery(".result").html(results);
var message=$('#result');
message.scrollTop(message[0].scrollHeight);
}
});
}
t = setInterval(refresh_div,1000);
</script>
here is the comment.php file, if needed-
<?php
session_start();
if(!isset($_SESSION['uid'])){
header('location:login.php');
}
include('config.php');
$sql = "SELECT * FROM messages ORDER BY id ASC LIMIT 0, 30 ";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result)) {
$uname=$row['uname'];
$message=$row['message'];
echo "<span>".$uname."</span>";
echo ": ";
echo "<span style='font-family:myfont2;'>".$message."</span>";
echo "<br>";
}
?>
I read that image caching can solve the problem, but i expect an AJAX solution only if possible.
EDIT- You guys suggested me to keep old messages loaded and "Get only newest data in ajax". I believe I cannot do this on my own and expecting some code help.
Thanks
EXTRA NOTE- This is my first question here so my apologies if i didn't asked or explained it well or asked something i shouldn't have asked. Hope you good guys out there understand :)
You might consider using Etags.
The idea is simple - the comments.php adds an additional HTTP header (thus not breaking the existing functionality) which in some way allows the client (your Javascript) to ask the server "Only send me the updated content if it's changed since the version I already have").
The server-side needs to generated some sort of determinative value (it only changes if the data in the database changes - like a SHA hash) and provides that as an Etag value along with the response.
Your client (jQuery can do this for you) caches the Etag value, and on future requests includes the cached Etag in the request. If the server determines that the new response would result in an identical Etag (nothing changed) - it responds with a 304 Not Modified.
Wikipedia on Etags: https://en.wikipedia.org/wiki/HTTP_ETag
Etags in jQuery (see "ifModified" on the page): http://api.jquery.com/jquery.ajax/
For a quick demonstration of doing it in PHP: https://css-tricks.com/snippets/php/intelligent-php-cache-control/
Here they're using the modified time and MD5 hash of a file on disk. You'd need to modify these values to be appropriate for your SQL query result (you could base it off an auto-incrementing primary key from the comment table, for example, plus a DEFAULT CURRENT_TIMESTAMP()).

setInterval doesn't seem to re-execute php script

what i'm trying to do is get a variable to update every 5 seconds doing this:
setInterval(document.getElementById("listeners").innerHTML =
"<?php include('../includes/shoutcaststuff.php');
echo $dnas_data['CURRENTLISTENERS']; ?>",5000);
but what happens is the inner html is set but doesn't update every 5 seconds like it should.
my guess is that the php only executes once, but i have no idea if that's the case or not.
and i'm aware i should make a function to do the stuff inside setInterval... i'll clean up the code once i figure out how to make it work.
thanks in advance.
ok... ajax was 'the best' answer since no more than 2 people would be logged in at a time here so server requests isn't such a big deal.
here's how i got it to work:
function lCount(){
$.get("../includes/shoutcaststuff.php",{Count: "TRUE"}, function(data){
document.getElementById('listeners').innerHTML = data;
});
}
setInterval(lCount,5000);
and added this to the end of the php:
if(isset($_GET["Count"])){
echo $dnas_data['CURRENTLISTENERS'];
}
now it works fine.
thanks for the suggestions guys :)
<?php include('../includes/shoutcaststuff.php');
echo $dnas_data['CURRENTLISTENERS']; ?>
This code only executes once when the page is built. For the rest of the times this javascript is called whatever is first echoed will be the value.
Instead of using a static value here, you are going to need to use an ajax request (or a websocket if you want to use html5). The request will then hit your server once every 5 seconds. Keep in mind that this can cause undue load on your server.
Ratchet is a commonly used PHP WebSocket implementation that allows for data to be sent to the client using push technology. This is probably more preferable than using your polling approach.
PHP code is run on the server generating the HTML/JS. Use ajax if you need to run php code once the page has loaded.
Take a look at this for example;
Using this:
setInterval(document.getElementById("listeners").innerHTML =
"<?php echo "1";?>",5000);
Will output this to the browser:
setInterval(document.getElementById("listeners").innerHTML =
"1",5000);

PHP $_GET and $_POST are returning empty arrays--trying to paginate SQL data

I have set up the following:
Database class ($db)
Pagination class ($paginator)
I am attempting to write a basic system to let me administrate pages. I have a page "page_manager.php" in which I include both my database class (database.php) and my pagination class (paginate.php).
In my pagination class I have a function which echoes my SQL data. I've come up with a way to echo an HTML < select > element with the necessary IDs, which allows me to successfully echo the corresponding results (10 per page), based on the value of the < select > element. So, "1" will echo the first 10 results in the database, "2" will echo from 11-20, "3" will echo from 21-30, etc., etc..
I have added an onChange event to the < select > element which will copy its value (using "this.value") to a hidden form field. I then submit this form using document.getElementById().submit();
This will then add the $_GET variable to the URL, so the URL becomes ".../?pagenumber_form=X". However, when I try to grab this value back from the URL, the $_GET['pagenumber_form'] is empty.
Some code:
<span style='font-family: tahoma; font-size: 10pt;'>Page #</span>
<select id="page_number_selection"
onchange='javascript: document.getElementById("pagenumber_form").value = this.value;
document.getElementById("pagenumber").submit();'>
<?php
for($i = 1; $i <= $this->num_pages; $i++)
echo"<option id='" . $i . "'>" . $i . "</option>";
?>
</select>
<form name="pagenumber" id="pagenumber" action="" method="get">
<input type="text" name="pagenumber_form" id="pagenumber_form" />
</form>
So, I've tried using $_POST as well, but the same thing happens. I want to use $_GET, for a couple of reasons: it's easier to see what is happening with my values and the data I'm using doesn't need to be secure.
To recap: the $_GET variable is being added to the URL when I change the < select > element, and the corresponding value gets added to the URL as: ".../?pagenumber_form=X", but when I try to use the value in PHP, for example...
$page_number = $_GET['pagenumber_form'];
... I get a NULL value. :-(
Can anybody help me out please? Thank you.
EDIT:
I've just made a discovery. If I move my print_r($_GET) to my main index page, then the superglobals are returning as expected. My site structure is like this:
index.php
- JavaScript buttons use AJAX HTTP requests to include the "responseText" as the .innerHTML of my main < div >. The "responseText" is the contents of the page itself, in this case page_manager.php, which in turn includes pagination.php.
So in other words, my site is built from PHP includes, which doesn't seem to be compatible with HTTP superglobals.
Any idea how I can get around this problem? Thank you :-).
+------------------------------------------------------------------+
I can't answer my own posts, so:
The problem is not solved, but has been worked around.
I am certainly not very knowledgeable when it comes to PHP, but I am of the impression that using AJAX requests to include a PHP file in a document, which itself includes other PHP files, is not a good idea. The problem, I believe, was being caused because PHP is executed before the document is loaded in to the browser. Therefore, dynamically including a PHP file in a document will result in the improper working of said file due to the fact that PHP must be executed by the server before the page is rendered, and not after.
As such, I have stopped using AJAX for my site and am simply using good old PHP instead. I don't know enough to carry on using the AJAX requests, so that's an end to that problem.
Thanks to those who replied.
You need to re-pass the superglobals to the AJAX calls. So where you would make a request to pagination.php you need to make it to pagination.php?pagenumber_form=<?php echo $_GET['pagenumber_form']; ?>.
the corresponding value gets added to the URL as: ".../pagenumber_form=X
You might wanna try
.../?pagenumber_form=X
Included files can access superglobals just fine (which is what makes them super). What can't be done is to access variables from one request in another. It isn't that clear what your code is doing (since the question doesn't include a proper minimal test case–a complete, concise, representative sample), but it sounds like loading a single page involves multiple requests, and only the first of these is given the form data. Each AJAX request involves a separate HTTP request, and (because HTTP is supposed to be stateless) has different request data, so any request that isn't explicitly given the data won't have access to it. After a request is handled, all data the script has access to is discarded. This is why if you need data to exist across requests, you need some form of persistence, such as sessions (which you should be careful of, in order not to break the HTTP stateless model) or databases.
Some of the difficulty may lie in a confusion over exactly what happens server-side, what happens client-side, what happens between the two and in what order it all happens. Before you go further, read up on HTTP (a web search should reveal countless documents on the topic). You can use debuggers (e.g. Firebug, XDebug+a client, Wireshark, Live HTTP Headers) to peer at what's happening as it happens.

Optimizing jQuery speed

I am trying to use jQuery's fancy autocomplete function but I have a problem with speed of executing my script. Code snippet:
var data = <?php if(isset($names)) { echo json_encode(implode(" | ", array_unique($names))); } else { echo "null"; } ?>;
if (data != null) {
data = data.split(" | ");
$("#search_names").autocomplete(data);
}
My data comes from some MySQL table and is processed by PHP before jQuery pass it to input field. When I view source of such page there's enormous amount of text there (obviously) and the page itself loads between 5-10 seconds...
So I wonder is there a way to speed up my script somehow? I understand that there will be always so much text to process, whether in same file or in some other included file, but I just wonder am I stuck with 10sec loading page because of so much data or can I somehow make it more awesome? :)
Thanks for any help!
You should definitely use the remote autocomplete mechanism instead of filling all the data into the document every time.
The first argument can be an URL for remote data or an an array for local data.
For remote data: When the user starts typing, a request is send to the specified backend ("my_autocomplete_backend.php"), with a GET parameter named q that contains the current value of the input box and a parameter "limit" with the value specified for the max option.
if the lookups still take a lot of time, you will probably need to look into optimizing your PHP script instead of the jQuery part. Things like is the database using indexes, etc....
Looks like your using the following scritp: http://docs.jquery.com/Plugins/autocomplete
You should be using Ajax for this sort of thing, example:
$("#search_names").autocomplete('/ajax/autocomplete.php');
and then within your auto complete html you should do something like:
<?php
//Database
//Do Query: SELECT item FROM content WHERE {$escaped_q} ORDER BY item_hits DESC LIMIT {$escaped_limit}
//echo json_encode($results);
?>
Print the results as a JSON Object and it should work MUCH MUCH Faster.

how to hide a json object from source code of a page?

iam using json object in my php file but i dont want my json object to be displayed in source code as it increases my page size a lot.
this is what im doing in php
$json = new Services_JSON();
$arr = array();
$qs=mysql_query("my own query");
while($obj = mysql_fetch_object($qs))
{
$arr[] = $obj;
}
$total=sizeof($arr);
$jsn_obj='{"abc":'.$json->encode($arr).',"totalrow":"'.$total.'"}';
and this is javascript
echo '<script language=\'javascript\'>
var dataref = new Object();
dataref = eval('.$jsn_obj.');
</script>';
but i want to hide this $jsn_obj objects value from my source,how can i do that??? plz help !!
I'm not sure there's a way around your problem, other than to change your mind about whether it's a problem at all (it's not, really).
You can't use the JSON object in your page if you don't output it. The only other way to get the object would be to make a separate AJAX request for it. If you did it that way, you're still transferring the exact same number of bytes that you would have originally, but now you've added the overhead of an extra HTTP request (which will be larger than it would have been originally, since there are now HTTP headers on the transfer). This way would also be slower on your page load, since you'd have to load the page, then send the AJAX request and run the result.
There's much better ways to manage the size of your pages. JSON is just text, so you should look into a server-side solution to zip your content, like mod_deflate. mod_deflate works beautifully on dynamic PHP output as well as static pages. If you don't have control over your web server, you could use PHP's built in zlib compression.
Instead of writing the JSON date directly to the document instead you can use an XMLHttpRequest in or use a library like JQuery to load the JSON data during script runtime.
It depends largely on your json data. If the data you're printing inline in the html is huge you might wanna consider using ajax to load the json data. That is assuming you wanted your page to be loaded faster, even without data.
If the data isn't that big, try to keep the data inline, without making extra http requests. To speed up your page, try using YSlow! to see what other areas you could optimize.

Categories