0
\$\begingroup\$

I want to perform some operations on the gridview (asp.net 4.0). So, to achieve this i have written a jquery function which i am calling on pageload but, because this function takes some time for execution my grid performance degrades (IE 8). Can i optimize it someway?

     $.each($("#divTab2GridInquiries").find("tr").not(":first"), function () {
            var tr = $(this);
            var val = tr.find("input[id*='hdnLineStatus']").val();
            var btnDelete = tr.find("div[id='divBtnDelete']");
            var btnTobeDeleted = tr.find("div[id='divBtnTobeDeleted']");
            if (val == "N") {
                btnDelete.hide();
                btnTobeDeleted.hide();
            }
            if (val == "S") {
                tr.css("background-color", "#99FF99");
                tr.find("input").css("background-color", "#99FF99");
                btnDelete.show();
                btnTobeDeleted.hide();
            }

            if (val == "D") {
                tr.css("background-color", "#FFFF99");
                tr.find("input").css("background-color", "#FFFF99");
                btnDelete.show();
                btnTobeDeleted.hide();
            }

            //From user rights 
            if ($("input[id*='hdnTab2ShowDelete']").val() != "Y") {
                btnTobeDeleted.hide();
                //btnDelete.show();
            }
        });
\$\endgroup\$
2
  • 4
    \$\begingroup\$ Not an optimisation, but two comments: (1) You seem to have multiple elements with the same id, which is invalid html and should be avoided - use classes; (2) The first line will work but is using the "wrong" sort of .each(), so I'd say: $("#divTab2GridInquiries").find("tr").not(":first").each(function () { \$\endgroup\$
    – nnnnnn
    Commented Jul 20, 2012 at 3:34
  • \$\begingroup\$ Do you mean to always hide btnTobeDeleted.hide();? \$\endgroup\$
    – Bill Barry
    Commented Jul 21, 2012 at 2:26

3 Answers 3

3
\$\begingroup\$

Use a single selector instead of "find" and "not." Leave the find, this is faster in every browser except opera (see comments).

For the 2nd part of the selector, you can use the "sibling" combinator ~ to grab everthing except its first operand, and the :first-child pseudoclass selector to get the first child, giving you the same set of elements without using several jQuery methods. This is faster than using not(':first') in all browsers, and faster than a single selector (e.g. not using find either) in all browsers except Opera (which maintains its native-selector edge). See this test.

Note: #someTable tr will also return tr elements from a nested table. You really want to target the direct row descendants of the table. But don't forget about tbody, which is a required element. So this probably should be "#divTab2GridInquiries > tbody > tr:first-child ~ tr". But that is a mouthful... and it's really slow. If you have no nested tables it will work fine as coded below.

$.each($("#divTab2GridInquiries").find("tr:first-child ~ tr"), function () {      
    var tr = $(this);

Not sure what you're doing here - the selector is using a wildcard match, but val only operates against the first element in a selection set. Can you target this element more specifically? In any event, instead of wildcard matching the id, add a class and select on that. Classes are much faster than substring matching attributes.

        //var val = tr.find("input[id*='hdnLineStatus']").val();
        var val = tr.find(".hdnLineStatus").val();

IDs are supposed to be unique. I'm not sure why you would have to target it this way. But using an attribute selector like this will definitely be slower than a regular ID or class selector. If these ids are really unique then just use #divBtnDelete. I suspect that they aren't and you're creating invalid html. Get rid of the ID an add a class.

        // var btnDelete = tr.find("div[id='divBtnDelete']");
        var btnDelete = tr.find(".divBtnDelete");

        //var btnTobeDeleted = tr.find("div[id='divBtnTobeDeleted']");
        var btnTobeDeleted = tr.find(".divBtnTobeDeleted");

This set of ifs should be a switch, but that's probably not slowing you down nearly as much as the selectors.

        if (val == "N") {
            btnDelete.hide();
            btnTobeDeleted.hide();
        }
        if (val == "S") {
            tr.css("background-color", "#99FF99");h
            tr.find("input").css("background-color", "#99FF99");
            btnDelete.show();
            btnTobeDeleted.hide();
        }

        if (val == "D") {
            tr.css("background-color", "#FFFF99");
            tr.find("input").css("background-color", "#FFFF99");
            btnDelete.show();
            btnTobeDeleted.hide();
        }

Use a class again.

        //From user rights 
        //if ($("input[id*='hdnTab2ShowDelete']").val() != "Y") {
        if ($(".hdnTab2ShowDelete").val() != "Y") {

            btnTobeDeleted.hide();
            //btnDelete.show();
        }
    });
\$\endgroup\$
8
  • \$\begingroup\$ thanx for detailed explanation. I found what was slowing down foreach loop. my last condition : $("input[id*='hdnTab2ShowDelete']").val()!='Y' because while scanning each row of the table it was accessing outside hidden field. I fixed it \$\endgroup\$
    – Tuscan
    Commented Jul 20, 2012 at 3:50
  • \$\begingroup\$ Ha, I noticed that at first and then totally forgot by the time I got done :) yeah that would be a killer, since the wildcard match would have to be run against every input element on the DOM for each iteration of the loop. The other stuff can't hurt either. \$\endgroup\$
    – jamietre
    Commented Jul 20, 2012 at 3:53
  • \$\begingroup\$ Since selectors are always matched right to left, using find is actually much faster. \$\endgroup\$ Commented Jul 20, 2012 at 16:18
  • \$\begingroup\$ Learn something new every day. I have to say I am astounded that Chrome doesn't optimize even for ID selectors. Apparently they are not always matched this way, though, in your test results Opera's native operation is faster. \$\endgroup\$
    – jamietre
    Commented Jul 20, 2012 at 16:36
  • \$\begingroup\$ Was wondering about Opera myself. I'd really like to know what sort of witchcraft they're employing to get those results. \$\endgroup\$ Commented Jul 20, 2012 at 17:15
1
\$\begingroup\$

The best that I can see if changing the IFs to switches, but overall, the speed of execution will not change.

switch (val){

case "N":
// Code for N
break;

case "S":
// Code for S
break;

case "D":
// Code for D
break;

default:
// For the rest, use "not" to subtract Y from the equasion.
}
\$\endgroup\$
2
  • \$\begingroup\$ Op's issues are likely DOM traversal related (especially as IE8 is very slow at that), so, I kinda doubt this helps. \$\endgroup\$
    – JayC
    Commented Jul 20, 2012 at 3:37
  • \$\begingroup\$ I said that before I suggested any sort of code... \$\endgroup\$
    – TurdPile
    Commented Jul 20, 2012 at 3:42
1
\$\begingroup\$

I think you should use behind C# code in aspx.cs to do this. If the visibility and style of the elements(buttons, table cells) is NOT interactive.
This solution doesn't need javascript at all, and will get better performence in browsers.

\$\endgroup\$
8
  • \$\begingroup\$ ASP.NET rowdatabound is too slow. I dont think that will help because i am trying to improve my application performance \$\endgroup\$
    – Tuscan
    Commented Jul 20, 2012 at 3:52
  • \$\begingroup\$ ASP.NET rowdatabound run on the server, JS run in the browser. Your question is to optimize JS code, this can only affect the performance in browser, not the server side. If you use ASP.NET rowdatabound, you use the server to do the job, and leave Browser free. So your program's performance in browser is got optimized. \$\endgroup\$
    – Jerry
    Commented Jul 20, 2012 at 3:54
  • \$\begingroup\$ But, If we talk about overall performance which process will be faster? \$\endgroup\$
    – Tuscan
    Commented Jul 20, 2012 at 3:58
  • \$\begingroup\$ Server's are generally much faster than a personal computer. \$\endgroup\$
    – TurdPile
    Commented Jul 20, 2012 at 4:00
  • 1
    \$\begingroup\$ I haven't used webforms in a while but I remember gridview/listview being a huge pain to manipulate the individual row data in any way other than simple templating actions from the server. His demands here aren't excessive, this seems reasonable to do on the client. Templated grid controls that run entirely on the client are common these days and they actually perform a lot better than server models because of low latency & minimized data transfer, the only reason he had a performance problem was due to an egregious error with a selector. \$\endgroup\$
    – jamietre
    Commented Jul 20, 2012 at 4:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.