Causes of Slow AJAX?

JavaScript and client side scripting.

Moderator: General Moderators

Post Reply
User avatar
paqman
Forum Contributor
Posts: 125
Joined: Sun Nov 14, 2004 7:41 pm
Location: Burnaby, BC, Canada

Causes of Slow AJAX?

Post by paqman »

I've been testing out a site that uses a little AJAX here and there, and I've noticed that on some older computers, the response time is horrible. The javascript function removes table rows and replaces them with the newly retrieved values, and it's taking about a second for each row to be removed. On the same computer, I've noticed this problem for all similar applications (our help desk uses AJAX). My work computer is on the slow end, a single 1.73 GHz processor with 1 GB of ram, while my home computer (that I use to create websites) is a quad core with 3 GB of ram.

Maybe this is an open ended question, but if anyone has any advice, I'd appreciate it.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Causes of Slow AJAX?

Post by John Cartwright »

You'll have to give a lot more detail than that, specifically showing us the relevant code.

I would recommend jQuery if you havn't done so already, it is quite quick when dealing with the DOM.
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: Causes of Slow AJAX?

Post by pickle »

It's probably not the AJAX call itself that's causing the delay, but rather how you insert the response into the DOM that's taking a while.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
kaszu
Forum Regular
Posts: 749
Joined: Wed Jul 19, 2006 7:29 am

Re: Causes of Slow AJAX?

Post by kaszu »

and it's taking about a second for each row to be removed
Removing/adding/changing table rows is expensive (need to recalculate each column and table width + reflow), but 1 sec. is too much if you don't have 1000 columns. There must be something else going on.
Is there something else than text? Are you doing any calculations before/after inserting rows?
User avatar
paqman
Forum Contributor
Posts: 125
Joined: Sun Nov 14, 2004 7:41 pm
Location: Burnaby, BC, Canada

Re: Causes of Slow AJAX?

Post by paqman »

I've heard about jQuery but never used it - so it's worth looking into? This is maybe the 4th or 5th time I've used AJAX, and my goal each time is functionality. I've just tried to get it working, and then left it alone - there hasn't been any optimizing or anything, so I'm sure this code is quite clunky.

updateOutput() removes the current shopping basket listing and puts in the information passed through 'message'. sendBasket is for when they click to add an item - it updates their cart and then refreshes it, using updateOutput in the end to get the current basket.

Code: Select all

 
//update output area
function updateOutput(message, theid, theclass)
{
    //build new response
    var theCol = document.createElement("td");
    
        theCol.id = "output_" + theid;
        theCol.setAttribute("class", theclass);
        theCol.innerHTML = message;
        
    //rename existing response
    document.getElementById("output_" + theid).id = "toRemove";
    
    //insert the new row
    document.getElementById("toRemove").parentNode.insertBefore(theCol, document.getElementById("toRemove"));
    
    //remove old row
    document.getElementById("toRemove").parentNode.removeChild(document.getElementById("toRemove"));
}
    
    
//send a data request
function updateBasket(theid)
{   
    var quantity = document.getElementById("quantity_" + theid);
    var size = document.getElementById("size_" + theid);
    var item = document.getElementById("product_" + theid);
    
    if(quantity.value != "")
    {
        if(size.value != "")
        {
            sendBasket(item.value, size.value, quantity.value);
        }
        
        else
        {
            updateOutput("Please select a size", theid, "AJAXfail");
            document.getElementById("size_" + theid).focus();
        }
    }
    else
    {
        updateOutput("Please enter a quantity", theid, "AJAXfail");
        document.getElementById("quantity_" + theid).focus();
    }
    
 
        
}
</script>
 
 
    <script language="javascript">
    var async = false;
    if(window.XMLHttpRequest)
    {
        async = new XMLHttpRequest();
    }
 
    else if(window.ActiveXObject)
    {
        async = new ActiveXObject("Microsoft.XMLHTTP");
    }
 
 
    function sendBasket(item, size, quantity)
    {
        async.open("GET", "/basketupdate.php?item=" + item + "&size=" + size + "&quantity=" + quantity , true);
        async.onreadystatechange = getResponse;
        async.send(null);
    }
 
    
 
 
    //get the data sent back
    function getResponse()
    {
 
        if(async.readyState == 4 && async.status == 200)
        {
            
            var receivedText = async.responseText; //data as a string
            if(receivedText .indexOf('|' != -1))
            {
                element = receivedText.split('|');
                if(element[0] == "1")
                {
                    updateOutput("item added", element[1], "AJAXsucceed");
                    reloadBasket("short");
                }
                else
                {
                    updateOutput("could not add item", element[1], "AJAXfail");
                }
            } 
        } 
    }
    </script>   
User avatar
paqman
Forum Contributor
Posts: 125
Joined: Sun Nov 14, 2004 7:41 pm
Location: Burnaby, BC, Canada

Re: Causes of Slow AJAX?

Post by paqman »

When I'm on a dual or quad core, the slow parts are instantaneous. It's just when I'm on a single core that this all starts to slow down.
User avatar
paqman
Forum Contributor
Posts: 125
Joined: Sun Nov 14, 2004 7:41 pm
Location: Burnaby, BC, Canada

Re: Causes of Slow AJAX?

Post by paqman »

Sorry, that was for the other part of the page. The basket part is this:

Code: Select all

 
<script language="javascript">
    var theSync = false;
    if(window.XMLHttpRequest)
    {
        theSync = new XMLHttpRequest();
    }
 
    else if(window.ActiveXObject)
    {
        theSync = new ActiveXObject("Microsoft.XMLHTTP");
    }
 
 
 
 
 
    //send a data request
    function reloadBasket(detail)
    {   
        //remove old ones
        while(document.getElementById("basketRow"))
        {
            document.getElementById("basketRow").parentNode.removeChild(document.getElementById("basketRow"));
        }
        /*
        var rows = document.getElementsByName("basketRow");
        for (l = rows.length-1; l>=0; l--) 
        {
            rows[l].parentNode.removeChild(rows[l]);
        } */
        
        //put in 'loading...'
        var loadTR = document.createElement("tr");
            loadTR.id = "loadingText";
        var loadTD = document.createElement("td");
            loadTD.innerHTML = "<img src='/icon/loading.gif'> Loading...";
        loadTR.appendChild(loadTD);
        document.getElementById("basketShort").parentNode.insertBefore(loadTR, document.getElementById("basketShort")); 
        
        
        theSync.open("GET", "/basketupdate.php?getBasket", true);
        theSync.onreadystatechange = getContents;
        theSync.send(null);
    }
 
 
    //get the data sent back
    function getContents()
    {
 
        if(theSync.readyState == 4 && theSync.status == 200)
        {
            var receivedText = theSync.responseText; //data as a string
            if(receivedText .indexOf('%tr' != -1))
            {
                //remove 'loading...'
                document.getElementById("loadingText").parentNode.removeChild(document.getElementById("loadingText"));
                
                
                //go through each tr
                element = receivedText.split('%tr');
                for(i = 0; i < element.length; i++)
                {
                    var theTR = document.createElement("tr");
                    //theTR.setAttribute("name", "basketRow");
                    theTR.id = "basketRow";
                    
                    if(element[i] .indexOf('%td' != -1))
                    {
                        pieces = element[i].split('%td');
                        
                        //go through each td
                        for(j = 0; j < pieces.length; j++)
                        {
                            var theTD = document.createElement("td");
                            theTD.innerHTML = pieces[j];
                            theTD.vAlign = "top";
                            theTR.appendChild(theTD);
                        }
                        
                        //output row
                        document.getElementById("basketShort").parentNode.insertBefore(theTR, document.getElementById("basketShort"));
                    }
                    
                }
 
            }
        } 
    }
    </script>
 
User avatar
kaszu
Forum Regular
Posts: 749
Joined: Wed Jul 19, 2006 7:29 am

Re: Causes of Slow AJAX?

Post by kaszu »

updateOutput: instead of creating new cell and removing old, you can just change innerHTML and className

You shouldn't retrieve basketShort on each row insert

Code: Select all

document.getElementById("basketShort").parentNode.insertBefore(theTR, document.getElementById("basketShort"));

Code: Select all

var target_row = document.getElementById("basketShort");
...
for(...) {
    ...
    target_row.parentNode.insertBefore(theTR, target_row);
}
same when removing rows.
Post Reply