Jump to content

How can I optimize this PHP script to load the page faster? It's too slow


php_lover

Recommended Posts

 So I have this PHP script below that requests data from the Twitter API and then displays it on the page according to the information that I have in my local database because I stored twitter usernames of some twitter users so I can pass them to the API and display the profile images of those twitter users. The script works fine to display my request from the API but it is AWFULLY slow , so I was wondering what could cause the script to be so slow ... Below is my script .. the first part seems to execute fine...

 

    /* Create a TwitterOauth object with consumer/user tokens. */
    $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']);
    $url = $connection->get('statuses/user_timeline', array('screen_name' => $row['Twitter'],count=>'1'));
             $results  = json_encode($url);
             $data = json_decode($results, true);
             $image = '';  
             if(is_array($data)){  
             $image = $data[0]['user']['profile_image_url']; 
             $image_bigger = str_replace('_normal', '_bigger',$image); 
     }
     echo "<h1 align='middle' id = $id> $name Vs Opposition </h1>";
     echo "<img src='".$image_bigger."' width= '100' height ='100' class= 'image' align='middle' />";
    ?>


//This part of the script below seems to be the culprit of the page taking so long to display info because it loops through all the twitter IDs returned by the query in order to display the images of the authors that I request through the API inside the loop . $data2 variable is very long array of info regarding the twitter user and from that array , I pick the key of the array containing the value that stores the picture of every twitter user inside a loop .. How could I dynamically optimize this so I can get all those images ?  

   



     <?php
        $select2  = "SELECT * FROM AUTHORS WHERE ID <> $id";  
        $result2 = mysql_query($select2);
        $result_count = mysql_num_rows($result2);
        $image_array = array();
        $unique_id = array();
        $counter = 0;
        if($result_count > 0) { 
        while ($row2 = mysql_fetch_array($result2, MYSQL_ASSOC)) { 
        array_push($unique_id, $row2['ID']);
        $url2 = $connection->get('statuses/user_timeline', array('screen_name' => $row2['Twitter'],count=>'1'));
                 $results2  = json_encode($url2);
                 $data2 = json_decode($results2, true);   // data through is a very long array
                  $image2 = $data2[$counter]['user']['profile_image_url'];  
                  $image3 = str_replace('_normal', '_bigger',$image2);
                  array_push($image_array,$image3); 
        
               }
         }
        var_dump($data2); exit;
        ?>
               
        <div id="test">
        <iframe id="frame" src="" width="100%" height="100% frameBorder="0" ">
           </iframe>
        </div>
        <div id ="opposition">
        <?php
         $unique_image = array_unique($image_array);
         $id_array = array_unique($unique_id);
          $i = 0;
          foreach($unique_image as $content) {
         echo "<a id ='".$id_array[$i]."' href ='#'><img src='".$content."'  width= '100' height ='100'  class='image' /></a>";
         $i++;
        }
        ?>
        </div>


Link to comment
Share on other sites

If I was going to grab a bunch of data from a server that may or may not be reliable, since it's not my responsibility to manage its reliability, I would consider using an asynchronous call to grab said images. You could even implement some sort of lazy loading so you don't grab any images you don't need.

 

Worst case if twitter bombs out on you, you have an entire website, minus some images from twitter. When you make an api call in the back end, things can become quite unpleasant, especially if you are not doing any sort of error handling around that twitter oauth lib.

 

Nothing hurts my soul more than an Uncaught Exception, aka, the fatal error that got away.

Edited by The Letter E
Link to comment
Share on other sites

I don't know the twitter api at all, but based on your code sample you appear to be making a separate request to the twitter service for every row that your query returns. If your query returns say 20 rows, that's 20 individual requests. Assuming twitter is running smooth and answers each request in say 60ms time that's 1.2 seconds just talking with twitter + whatever time it takes to do on your end for processing. The more results you have, or the slower twitter is at responding, the slower the page load is going to be.

 

What you should do is find out from the API docs (or someone) whether it is possible to get the information for ALL of the twitter users you need in just one call. If that is not possible there may be alternative ways to accomplish what you are doing, such as an async method like mentioned above.

Link to comment
Share on other sites

If I was going to grab a bunch of data from a server that may or may not be reliable, since it's not my responsibility to manage its reliability, I would consider using an asynchronous call to grab said images. You could even implement some sort of lazy loading so you don't grab any images you don't need.

 

Worst case if twitter bombs out on you, you have an entire website, minus some images from twitter. When you make an api call in the back end, things can become quite unpleasant, especially if you are not doing any sort of error handling around that twitter oauth lib.

 

Nothing hurts my soul more than an Uncaught Exception, aka, the fatal error that got away.

Hello Letter E , thanks for taking the time to answer .. But how would I make an asynchronous call to the twitter API .. I'm only used to PHP .. Could you give me a hint or an example if you dont mind ?  I'd appreciate it a lot . Thanks !!

Link to comment
Share on other sites

As an example. By default all images will show a spinner and when the document has been loaded it will fire X number of ajax requests to get the twitter images.

 

You can further improve this with a lazy-loading image script (google that) which means that only when the user scrolls down and the image is "viewed" will it fire the AJAX request.

 

<img src="spinner.gif" alt="" class="load-author-image" data-twitter-screen-name="..">

<script>
  $(function() {
    $('.load-author-image').each(function(node) {
      $.ajax('get-author-image.php', { 'twitter-screen-name': $(node).data('twitter-screen-name') }, function(data) {
        node.src = data;
      });
    });
  });
</script>
Additionally you could cache images instead of requesting them over and over again from the Twitter API. Or you could simply use a cron to get the images and store the paths in your database. Edited by ignace
Link to comment
Share on other sites

You could just link the images to a PHP script that then determines which image to get. Eg:

<img src="get-author-image.php?screen_name=<?=urlencode($row2['Twitter'])?>">
<?php
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']);
$data = $connection->get('statuses/user_timeline', array('screen_name' => $_GET['screen_name'], count=>'1'));
if(is_array($data)){  
   $image = $data[0]->user->profile_image_url; 
   $image = str_replace('_normal', '_bigger', $image);
}
else {
   $image = 'http://www.example.com/blank.png'; //Some default image incase the lookup fails
}

header('Location: '.$image);
?>
Link to comment
Share on other sites

You could just link the images to a PHP script that then determines which image to get. Eg:

<img src="get-author-image.php?screen_name=<?=urlencode($row2['Twitter'])?>">
<?php
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']);
$data = $connection->get('statuses/user_timeline', array('screen_name' => $_GET['screen_name'], count=>'1'));
if(is_array($data)){  
   $image = $data[0]->user->profile_image_url; 
   $image = str_replace('_normal', '_bigger', $image);
}
else {
   $image = 'http://www.example.com/blank.png'; //Some default image incase the lookup fails
}

header('Location: '.$image);
?>

First of all , thanks for taking the time to try to help .. but the problem is this one , I'm basically trying to get the images of all the twitter user names inside the while loop , the twitter usernames of the users whose images I want to fetch through the twitter API , so I'm not quite sure how the script you wrote above would speed up the process of getting all the images , if you look at my code in my question , I first query my local MYSQL database to get the twitter usernames , and then make a request to the twitter API to return the profile image of the the user whose twitter username I passed to the API .. Does this make sense ?  so this is an example of the link generated by the API which returns data ... How can I make it faster with AJAX using this url instead ?  

https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterapi&count=1

Link to comment
Share on other sites

As an example. By default all images will show a spinner and when the document has been loaded it will fire X number of ajax requests to get the twitter images.

 

You can further improve this with a lazy-loading image script (google that) which means that only when the user scrolls down and the image is "viewed" will it fire the AJAX request.

 

<img src="spinner.gif" alt="" class="load-author-image" data-twitter-screen-name="..">

<script>
  $(function() {
    $('.load-author-image').each(function(node) {
      $.ajax('get-author-image.php', { 'twitter-screen-name': $(node).data('twitter-screen-name') }, function(data) {
        node.src = data;
      });
    });
  });
</script>
Additionally you could cache images instead of requesting them over and over again from the Twitter API. Or you could simply use a cron to get the images and store the paths in your database.

 

Hello Ignance .. Thank you so much for taking the time to respond ... I see that you're from Belgium .. I have a brother there and je parle francais aussi :-)  I am not sure I quite understand what you were trying to tell me ... As you can see , I try to fetch images from multiple users inside a loop based on the twitter username of the user I pass to the twitter API service in order to return the image .. The url generated by the API is this one 

 

https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterapi&count=1  ..

 

Is there a way I can pass this link through Jquery AJAX and get the images much quicker instead of waiting for minutes for the php to return the data because the page keeps loading for a minute . I'm so new to the Jquery & AJAX world .. How would you use the url above to fetch the images , yet embed it in the PHP code I have ?  Your response would be much appreciated , and if I misunderstood what you were explaining , please let me know :-)

Link to comment
Share on other sites

 

First of all , thanks for taking the time to try to help .. but the problem is this one , I'm basically trying to get the images of all the twitter user names inside the while loop , the twitter usernames of the users whose images I want to fetch through the twitter API , so I'm not quite sure how the script you wrote above would speed up the process of getting all the images , if you look at my code in my question , I first query my local MYSQL database to get the twitter usernames , and then make a request to the twitter API to return the profile image of the the user whose twitter username I passed to the API .. Does this make sense ?  so this is an example of the link generated by the API which returns data ... How can I make it faster with AJAX using this url instead ?  

https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterapi&count=1

 

SMART IDEA , I get your idea now !!!!

Link to comment
Share on other sites

 

First of all , thanks for taking the time to try to help .. but the problem is this one , I'm basically trying to get the images of all the twitter user names inside the while loop , the twitter usernames of the users whose images I want to fetch through the twitter API , so I'm not quite sure how the script you wrote above would speed up the process of getting all the images , if you look at my code in my question , I first query my local MYSQL database to get the twitter usernames , and then make a request to the twitter API to return the profile image of the the user whose twitter username I passed to the API .. Does this make sense ?  so this is an example of the link generated by the API which returns data ... How can I make it faster with AJAX using this url instead ?  

https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterapi&count=1

 

Question though .. since you're passing parameters to the <img> tag .. wouldn't that have to be a URL for it to work ?  I'd like the image to be displayed without having to click on it to go to the processing script ?  hope I am not confusing you .

Link to comment
Share on other sites

Hello Ignance .. Thank you so much for taking the time to respond ... I see that you're from Belgium .. I have a brother there and je parle francais aussi :-)  I am not sure I quite understand what you were trying to tell me ... As you can see , I try to fetch images from multiple users inside a loop based on the twitter username of the user I pass to the twitter API service in order to return the image .. The url generated by the API is this one 

 

https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterapi&count=1  ..

 

Is there a way I can pass this link through Jquery AJAX and get the images much quicker instead of waiting for minutes for the php to return the data because the page keeps loading for a minute . I'm so new to the Jquery & AJAX world .. How would you use the url above to fetch the images , yet embed it in the PHP code I have ?  Your response would be much appreciated , and if I misunderstood what you were explaining , please let me know :-)

I think I get what you were trying to tell me after re-reading your code .. Let me try this and I'll get back to you .. Thanks a bunch

Link to comment
Share on other sites

Question though .. since you're passing parameters to the <img> tag .. wouldn't that have to be a URL for it to work ?  I'd like the image to be displayed without having to click on it to go to the processing script ?  hope I am not confusing you .

It is a URL, and there is no clicking required for it to pull the image. You output an image tag such as:

<img src="get-author-image.php?screen_name=someHandle">
When the browser sees that it will make a request to get-author-image.php?screen_name=someHandle in order to load that image. That script then contacts the twitter api, locates the correct image URL for the given handle and forwards the browser there using a Location: header.
Link to comment
Share on other sites

It is a URL, and there is no clicking required for it to pull the image. You output an image tag such as:

<img src="get-author-image.php?screen_name=someHandle">
When the browser sees that it will make a request to get-author-image.php?screen_name=someHandle in order to load that image. That script then contacts the twitter api, locates the correct image URL for the given handle and forwards the browser there using a Location: header.

 

Kicken , I tried your method and it's not working ... Although the php script to get the images redirect to the image link of the twitter user , it doesn't show the image with the img tag ... My suspicion is because the img tag executes fast and doesn't wait for the PHP script to finish doing its job ... Thanks for trying to help though.

Link to comment
Share on other sites

That made no sense.

The image tag is parsed (it doesn't execute) by the client, the browser. The PHP file is executed at the server, which is at a completely different time than when the browser parses the HTML. HTML is not parsed until PHP has completed the execution, and the PHP file in the image src is a completely different PHP file to the one that generated the image tag in the first place.

 

If you have troubles with the script that generates and outputs the image tags, try visiting it directly. Save the results in a file, or show it directly in the browser. Most likely you've got some PHP errors in there, which causes the image data to become corrupted.

Link to comment
Share on other sites

My suspicion is because the img tag executes fast and doesn't wait for the PHP script to finish doing its job ...

The browser has to wait for the PHP script to complete. If you're not seeing an image, then either the PHP script is incorrect and returning bad data, or your browser is somehow incorrectly processing the data being returned. Use the browser's debug tools to see what is going on and if there are any errors being reported. Looking at the requests being made would be a good place to start, to see if the browser is 1) requesting the PHP script and 2) following that with a request for the twitter image. If your browser doesn't have such a tool, you can use something like Fiddler

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.