0

Hi, im trying to do a ajax live search. It work`s, but i want it to be fast. Currently i`m processing the html by php, but even if i change the processing to js and only get the data from php it only improves my search from 2.1 to 1.8 seconds (this is the request time, but it takes 4/5 seconds for the data to appear)

Heres my code:

$("#searchfield").change(function() {
    term = $(this).val();
    if (searchReq != false) {
    searchReq.abort();
    }
    searchReq = $.get("/searchModal.php", {
        term : term
    }).done(function(data) {
        $("#liveSearch").html(data);
    });

});

EDIT:

php code:

search.php:

$files = filecontroller::search($term);

file controller:

public static function search($term, $by = false, $order = false) {
    connection::connect();

    $files = ($by && $order && validation::filesOrder($by, $order)) ? file::Search($term, $by, $order) : file::Search($term);

    return $files;
}

File model:

public static function Search($term, $by = 'date', $order = 'DESC') {

    $session_id = $_SESSION["user_id"];
    $term = mysql_real_escape_string($term);
    $query = mysql_query("SELECT * FROM files WHERE idUser = '$session_id' AND (name LIKE '%$term%' OR description LIKE '%$term%') ORDER BY $by $order");

    $files = self::CreateFromDb($query);
    return $files;

}

private static function CreateFromDb($query) {
    GLOBAL $imgDir; // just get the img dir from a config file
    GLOBAL $userDir; // same
    $files = array();
    while ($row = mysql_fetch_assoc($query)) {

        $file = new File();
        $file -> type = $row['type'];

        $file -> idFile = $row['idFile'];
        $file -> user = $row['idUser'];
        $file -> gallery = $row['idGallery'];
        $file -> name = htmlspecialchars($row['name']);
        $file -> description = htmlspecialchars($row['description']);
        $file -> date = $file -> timecheck($row['date']);
        $file -> size['kb'] = $row['size'];
        $file -> galleryName = Gallery::getName($file -> gallery);

        $files[] = $file;
    }

    return $files;
}

Is there anyway to improve it? Im testing in local.

Renato Probst
  • 5,914
  • 2
  • 42
  • 45
  • It sounds like your search query is the slow part. Have you benchmarked any of this? – MonkeyZeus Feb 26 '14 at 20:39
  • Anything above a 1 second response time means you are doing something terribly wrong on the backend or you have a terrible connection / hosting / infrastructure. – PeeHaa Feb 26 '14 at 20:40
  • 1
    You can use the timeline and network analysis tools in Chrome, for example, to see where this huge delay is introduced. If you run everything on the same machine, it should be searchModal.php that is slow for some reason. Please supply the code. – André Laszlo Feb 26 '14 at 20:40
  • Using any modern web browser (IE8 and later) you will need to open up the Developer Tools, find the Network Tab and activate the AJAX call to see what sort of network latency you are experiencing. Since you said this was localhost then odds are that the issue lies in your PHP script. – MonkeyZeus Feb 26 '14 at 20:40
  • Thanks, i added the php code. 2.20 seconds on waiting on chrome, i was using opera for debug, same. – Renato Probst Feb 26 '14 at 20:58

2 Answers2

2

There are some issues with your code, but nothing obvious.

Some starting points:

  • The best way to find what's slow is probably to check profiling in PHP.
  • Another thing is that you're using LIKE "%x%" which will be slow if your user has lots of files (seems unlikely, but who knows). Check the MySQL slow query log.
  • You're also doing some disk access, but it shouldn't be this slow either - unless something strange is going on inside Gallery::getName or timecheck.
  • Note that the mysql extension has been deprecated. This has nothing to do with speed though, it's just outdated.
Community
  • 1
  • 1
André Laszlo
  • 15,169
  • 3
  • 63
  • 81
  • Thank you for the tips. Why disk acess? getName just get a bd name (gallery is just a pseudo folder), altrought it do another query, but i can`t get ride of it. I`l try the profiling, havent heard about this technic before. I`l try to check if the request is being made in time too, cause it taking a lot of time to start the request (seens like it freezes on 0ms for some secs), maybe some apache or anti virus (localhost) issue? – Renato Probst Feb 26 '14 at 22:19
  • If you're running the whole thing locally, the db is small, and so on, the antivirus might actually be slowing connections down. Good idea. – André Laszlo Feb 27 '14 at 07:10
0

ANSWER

.change has a delay, for real time results its better to use .keyup. I cme up using a timeout to make the request only when user stop typing:

var searchTimeout;
var searchReq;

$("#searchfield").on('keyup', function() {
    term = $(this).val();

    if (searchTimeout) {
        clearTimeout(searchTimeout);
    }
    if (searchReq) {
        searchReq.abort();
    }

        searchTimeout = setTimeout(function(){
        if (term.length > 2) {
            searchController(term).then(function(data) {
            $("#liveSearch").html(data);
            });
        }
        else {
            $("#liveSearch").html("");
        }
    },500);

});

function searchController(term) {
    searchReq = $.ajax({
        type : "GET",
        url : "/searchModal.php",
        data : {
            term : term
        },
        async : true,
        context : this,
        beforeSend : function() {
        },
        complete : function() {

        }
    });
    return searchReq;

}

Its still slow compared to facebook, and other big sites. I guess the only way to acess it fast would be with a great server or cached results (i tried to just echo an string without bd requests and its slow too).

Renato Probst
  • 5,914
  • 2
  • 42
  • 45