Ian Campbell
Ian Campbell

Reputation: 2748

Why is this Ajax taking so long to render?

I have a page that has primarily dynamic content generated by Ajax. It is randomized every 30 seconds, and new content from the database appears. The PHP seems fine, but there either seems to be something wrong with my Javascript code or there is a problem on the database causing it to lag (the Ajax takes about 30 seconds to load!)

It would seem as if the recursive call to setInterval in my Javascript is waiting the alloted milliseconds before executing the function, but I can't find any errors in my Javascript.

Also, there are two image url Strings retrieved from the database, and it seems plausible that Ajax would lag when it has to retrieve information from external sources.

Or maybe is there a lag in my usage of the PHP-MySQL syntax ORDER BY rand()?

Here is the relevant html:

    <html>
    <head>
    <title></title>
    <script type = "text/javascript" src = "randomProducts.js" />
    <script type = "text/javascript">
    setIntervalOnload();
    </script>
    </head>
    <body>
    ...
    ...
    ...
    </body>
    </html>

Here is the relevant Javascript:

    // global static variables
        var subCategory; // initialized from setCategoryTree
        var t; // for setInterval and clearInterval

        var seconds;
        var millisecondsPerSecond;
        var milliseconds;

    function setIntervalOnload()
    {
        getRandomProducts();
        if(typeof t != "undefined")
            clearInterval(t);

        seconds = 30;
        millisecondsPerSecond = 1000;
        milliseconds = seconds * millisecondsPerSecond;

        t = setInterval(getRandomProducts, milliseconds);
    }

    function getRandomProducts()
    {
        //window.alert(subCategory);
        if(typeof subCategory == "undefined")
            subCategory = "all";
        else
        {
            clearInterval(t);
            t = setInterval(getRandomProducts, milliseconds);
        }

        var req = new XMLHttpRequest();

        var products = document.getElementById("products");

        req.onreadystatechange = function()
        {
            if( (req.readyState == 4) && (req.status == 200) )
            {
                var result = req.responseText;
                products.innerHTML = result;
            }
        };
        req.open("GET", "randomProducts.php?category=" + subCategory, true);
        req.send(null);
    }
    function setCategoryTree(link)
    {
        var categoryTree = document.getElementById("categoryTree");

        /* climbing the DOM-tree to get the category name (innerHTML of highest "a" tag) */
        var category = link.parentNode.parentNode.parentNode.getElementsByTagName("a")[0].innerHTML;

        subCategory = link.innerHTML;

        categoryTree.innerHTML = "==>&nbsp;" + category + "&nbsp;&nbsp;==>&nbsp;" + subCategory;

        getRandomProducts();
    }

...and here is the relevant PHP:

<?php

    // connect to MySQL
    $dbName = "blah";
    $db = mysql_connect("localhost", $dbName, "asdf");
        if (!$db)
        {
             echo "<p>Error - Could not connect to MySQL</p>";
             exit;
        }

    // select the blah database
    $blah = mysql_select_db("blah");
        if(!$blah)
        {
            echo "<p>Error  - Could not select the blah database.</p>";
            exit;
        }

    // fix html characters in $subCategory
    $subCategory = $_GET["category"];
    trim($subCategory);
    $subCategory = stripslashes($subCategory);
    $subCategoryFixed = htmlspecialchars($subCategory);

    // for loop for each random product (total of 10 random products)
    for($i = 0; $i < 10; $i++)
    {
        // query the blah database for all products
        if($subCategoryFixed == "all")
        {
            $query = "SELECT * FROM products ORDER BY rand();";
            $result = mysql_query($query);
        }
        else // query the blah database for products in selected subCategory
        {
            $query = "SELECT * FROM products WHERE cat = " . $subCategoryFixed . " ORDER BY rand();";
            $result = mysql_query($query);
        }
            if (!$result)
            {
                echo "<p>Error - the query could not be executed</p><br />";
                $error = mysql_error();
                echo "<p>" . $error . "</p>";
                exit;
            }

        $row = mysql_fetch_array($result);
        $productValues = array_values($row);

        $name = htmlspecialchars($productValues[3]);
        $price = htmlspecialchars($productValues[5]);
        $img = htmlspecialchars($productValues[7]);

        // product info is formatted for home.html here
        $str = '<div>
                    <a href = "' . $link . '" title = "' . $name . '">
                        <table id = "product-table" onmouseover = "darkenProduct(this);" onmouseout = "lightenProduct(this);">
                            <tr>
                                <td>' . $name .'</td>
                            </tr>
                            <tr>
                                <td><img src = "' . $img . '" /></td>
                            </tr>
                            <tr>
                                <td>' . $price . '</td>
                            </tr>
                        </table>
                    </a>
                </div>';
        echo $str;
    } // end of products for loop
?>

Upvotes: 2

Views: 416

Answers (2)

mellamokb
mellamokb

Reputation: 56769

You are not running your code inside of onload method. It is possible that the AJAX setup code runs faster than the page can load so var products = ... is null. You need to do something like the following:

<body onload='setIntervalOnload();'>

or

 window.onload = setIntervalOnload;

Upvotes: 3

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324640

setInterval does not call the function immediately. The first run of the function will be delayed by however much the interval is.

You have to specifically call the function yourself if you want it to run immediately as well as on a timer.

Upvotes: 0

Related Questions