Question about performance in IE

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gui Lloyd

    Question about performance in IE

    I have a problem with performance in IE.
    The script above works quite fine when the table has a small number of
    elements, but, when the table has 2500 elements, when I click in the
    checkbox of the table header (to select all the checkboxes in table),
    the script demands at least 3 minutes to execute. I tested the same
    script in Mozilla and the response time is much more faster. Does
    anyone has an idea?

    <script>
    function checkFieldAll(f ieldName, checked) {

    // Defining the prefix and sufix of the indexed parameter
    var prefix = fieldName.subst ring( 0,
    fieldName.index Of('[') );
    var sufix = fieldName.subst ring( fieldName.index Of(']',
    prefix) + 1 );

    // Looking for the parameters to be treated matching the
    sufix and prefix
    var allFields = this.document.f orms[0].elements;
    var fields = new Array();
    for (i = 0; i < allFields.lengt h; i++) {
    var name = allFields[i].name;
    if(name != undefined){
    if (name.indexOf(p refix) == 0 &&
    name.indexOf(su fix) > name.indexOf(pr efix)) {
    var elem = allFields[i];
    fields.push(ele m);
    }
    }
    }

    // check/uncheck the fields
    for (i = 0; i < fields.length; i++) {
    fields[i].checked = checked;
    }
    }

    function onChangeCheckAl l (checkObject, fieldName) {
    checkFieldAll(f ieldName, checkObject.che cked);
    }
    </script>

    and in HTML I have something like:

    <table id="lockingsLis t" class="noScroll edList" >
    <tr class="noScroll edList">
    <th class="noScroll edListHeader" rowspan="2" >
    <input type="checkbox" onclick="javasc ript:onChangeCh eckAll(this,
    'lockingsList[].isChecked');">
    </th>
    <th class="noScroll edListHeader" rowspan="2" >
    Mnemonic
    </th>
    </tr>

    <tr class="listCell Alternate1">
    <td class="listCell ">
    <input type="checkbox" name="lockingsL ist[0].isChecked"
    value="on" id="lockingsLis t_0_isChecked">
    <input type="hidden"
    name="lockingsL ist[0].isChecked__gen erated_field__"
    value="__FALSE_ CHECKBOX__"
    id="lockingsLis t_0_isChecked__ generated_field __">
    </td>
    <td class="listCell "><span
    id="lockingsLis t_0_mnemonic">P 09_H67-1</span>
    </td>
    </tr>
    ......
    </table>
  • Lee

    #2
    Re: Question about performance in IE

    Gui Lloyd said:[color=blue]
    >
    >I have a problem with performance in IE.
    >The script above works quite fine when the table has a small number of
    >elements, but, when the table has 2500 elements, when I click in the
    >checkbox of the table header (to select all the checkboxes in table),
    >the script demands at least 3 minutes to execute. I tested the same
    >script in Mozilla and the response time is much more faster. Does
    >anyone has an idea?[/color]

    In the first place, IE is just slower at some things than Mozilla.
    However, you've got some inefficiencies:

    [color=blue]
    > if (name.indexOf(p refix) == 0 &&
    >name.indexOf(s ufix) > name.indexOf(pr efix))[/color]

    The second comparison never executes unless the first one is true.
    That means that there's no reason to execute name.indexOf(pr efix)
    a second time. You know that the value must be 0:

    if (name.indexOf(p refix) == 0 && name.indexOf(su fix) > 0 ) {

    Why copy the elements into an array and then loop through that
    array to set the value of checked? Just set each one as you
    find it.

    There are probably other things about the page that can be
    used to improve performance. If you want to set all of the
    checkboxes in the form, then don't bother looking at their
    names, just check to see if the type attribute is "checkbox".

    Similarly, if you have two columns of checkboxes, and only want
    to set one, then you should be able to just set every other
    checkbox. Or if you know that there are other fields, but that
    every 5th one is a checkbox, you can loop through touching only
    every 5th element, etc.

    Comment

    • Yann-Erwan Perio

      #3
      Re: Question about performance in IE

      Lee wrote:

      <snip excellent advice>
      [color=blue]
      > There are probably other things about the page that can be
      > used to improve performance.[/color]

      One that should increase the speed considerably is the for loop:

      Change from
      for (i = 0; i < allFields.lengt h; i++) {
      to
      for (var i = allFields.lengt h; i--;) {


      Regards,
      Yep.

      Comment

      • Mick White

        #4
        Re: Question about performance in IE

        Yann-Erwan Perio wrote:

        [color=blue]
        >
        > One that should increase the speed considerably is the for loop:
        >
        > Change from
        > for (i = 0; i < allFields.lengt h; i++) {
        > to
        > for (var i = allFields.lengt h; i--;) {
        >[/color]


        or:
        x=allFields.len gth;
        while(x--){ do stuff with x}

        Mick

        Comment

        • Richard Cornford

          #5
          Re: Question about performance in IE

          Gui Lloyd wrote:[color=blue]
          > I have a problem with performance in IE.
          > The script above works quite fine when the table has a small number of
          > elements, but, when the table has 2500 elements, when I click in the
          > checkbox of the table header (to select all the checkboxes in table),
          > the script demands at least 3 minutes to execute. I tested the same
          > script in Mozilla and the response time is much more faster. Does
          > anyone has an idea?[/color]

          On of the things that makes IE slowwer4 than Mozilla in some respects is
          the fact that IE uses a list-like implementation for its object, while
          Mozilla (and most other browsers) use a hash-table-like implementation.
          The effect is that as IE's objects get bigger it takes longer to resolve
          property names (of the properties towards the end of the list), While a
          hash-table-like object takes about as long to resolve property names
          regardless of size (or at least the difference isn't noticeable). The
          objects suffering that problem in your code are the - element -
          collection of the form and the Array. As Lee said, you don't need the
          Array at all. You can also loose the second look-up in the elements
          collection if you assign - allFields[i] - a reference to the form
          control to a local variable at that point.

          As Yep suggested, counting down in the - for - loop will be quicker
          because you don't have to resolve the length property on each iteration
          (and making - i - a local variable will make its use fractionally
          faster. But you might also try a - do{ ... }while(); - loop in its place
          as they can be faster than - for - loop (also counting down).
          [color=blue]
          > <script>
          > function checkFieldAll(f ieldName, checked) {
          >
          > // Defining the prefix and sufix of the indexed parameter[/color]

          Formatting code with a consideration of how newsreaders will present it
          is usually a good idea when posting to Usenet. See the FAQ:-

          <URL: http://jibbering.com/faq/ >
          [color=blue]
          > var prefix = fieldName.subst ring( 0,
          > fieldName.index Of('[') );
          > var sufix = fieldName.subst ring( fieldName.index Of(']',
          > prefix) + 1 );[/color]

          This looks wrong, and garbled code presentation is hiding it from other
          observers. Theoretically - prefix, has been assigned a string value, yet
          here you are using it as an argument to - indexOf -, and in the context
          of the "position". ECMA 262 calls for the positin argument to be subject
          to a call to the internal - ToInteger - function. If the string value
          of - prefix - represents an integer number then the result will be a
          number, but if - prefix - is a string that cannot be type-converted to a
          number by javascript the call to - ToInteger - will first convert that
          string to the number NaN and then return zero (as it is specified to do
          for number that are NaN).
          [color=blue]
          >
          > // Looking for the parameters to be treated matching the
          > sufix and prefix
          > var allFields = this.document.f orms[0].elements;
          > var fields = new Array();
          > for (i = 0; i < allFields.lengt h; i++) {
          > var name = allFields[i].name;[/color]

          So at this point:-

          var elem = allFields[i];
          var name = elem.name;
          [color=blue]
          > if(name != undefined){[/color]

          The - name - property of a form control element is of string type. It
          will be an empty string if no name was assigned, except maybe on some
          unusual implementations where it might actually be undefined. However,
          Type-converting comparison will never consider a string value (even an
          empty string) as equal to undefined, so this test will be passed by all
          elements under most circumstances. If you want to exclude controls that
          have no defined name attribute (so an empty string) and exclude the
          possibility that the corresponding name property may be undefined (for
          absolute safety) then a type-converting test will probably be quickest:-

          if(name){
          [color=blue]
          > if (name.indexOf(p refix) == 0 &&
          > name.indexOf(su fix) > name.indexOf(pr efix)) {[/color]

          As Lee said, the second execution of - name.indexOf(pr efix) - is
          unnecessary as you already know that it will return zero. The comparison
          in the first test may also not be needed as - !name.indexOf(p refix) -
          will only be true when - name.indexOf(pr efix) == 0 - is true. I don't
          know whether that would actually be quicker, there won't be much in it
          either way.

          Javascript also has the - lastIndexOf - method for String objects, and
          if you are expecting to find a suffix you would expect to find it at the
          end of a string. The balance of probability is that - lastIndexOf -
          implementations will search strings from end to start, and so fins
          suffixes quicker than - indexOf - (each will take (almost) exactly as
          long as the other when they fail to find a match) :-

          if ((!name.indexOf (prefix)) && (name.lastIndex Of(sufix) > 0)){

          [color=blue]
          > var elem = allFields[i];
          > fields.push(ele m);[/color]

          If - elem - was assigned earlier it does not need to be re-resolved
          against the (large) elements collection at this point. Assuming you drop
          the - fields - array, all that is left to do here is set the checked
          property:-

          elem.checked = checked;

          <snip>

          Combining all suggested changes may produce:-

          function checkFieldAll(f ieldName, checked){
          var prefix = fieldName.subst ring( 0, fieldName.index Of('[') );
          var sufix = fieldName.subst ring(fieldName. lastIndexOf(']') + 1);
          var allFields = this.document.f orms[0].elements;
          var name, elem, i;
          if((i = allFields.lengt h)){
          do{
          elem = allFields[--i];
          name = elem.name;
          if(
          (name = elem.name) &&
          (!name.indexOf( prefix)) &&
          (name.lastIndex Of(sufix) > 0)
          ){
          elem.checked = checked;
          }
          }while(i);
          }
          }

          Richard.


          Comment

          • Guilherme Lloyd

            #6
            Re: Question about performance in IE

            Thanks a lot Lee, Yann, Mick and Richard.
            The main problem was really in the "for (i = 0; i < allFields.lengt h;
            i++)", but all the suggestions improved a lot the code.
            Now the script takes 2 seconds with 2500 elements in table. Thanks a lot
            again. Cheers.


            *** Sent via Devdex http://www.devdex.com ***
            Don't just participate in USENET...get rewarded for it!

            Comment

            • Grant Wagner

              #7
              Re: Question about performance in IE

              Mick White wrote:
              [color=blue]
              > Yann-Erwan Perio wrote:
              >[color=green]
              > >
              > > One that should increase the speed considerably is the for loop:
              > >
              > > Change from
              > > for (i = 0; i < allFields.lengt h; i++) {
              > > to
              > > for (var i = allFields.lengt h; i--;) {
              > >[/color]
              >
              > or:
              > x=allFields.len gth;
              > while(x--){ do stuff with x}
              >
              > Mick[/color]

              <script type="text/javascript">
              for (var test = 0; test < 5; test++) {
              document.write( '<p>Test: ' + test + '<br>');

              var start = new Date();
              for (var i = 100000; i--;) { var x = 0; }
              document.write( 'for 99999 to 0: ' + ((new Date()).getTime () -
              start.getTime() ) + '<br>');
              var start = new Date();
              var i = 100000;
              while(i--) { var x = 0; }
              document.write( 'while 99999 to 0: ' + ((new Date()).getTime () -
              start.getTime() ) + '<br>');
              var start = new Date();
              for (i = 0; i < 100000; i++) { var x = 0; }
              document.write( 'for 0 to 99999: ' + ((new Date()).getTime () -
              start.getTime() ) + '<br>');

              document.write( '</p>');
              }
              </script>

              Internet Explorer 6SP1:

              Test: 0; for 99999 to 0: 190; while 99999 to 0: 200; for 0 to 99999:
              251
              Test: 1; for 99999 to 0: 190; while 99999 to 0: 210; for 0 to 99999:
              271
              Test: 2; for 99999 to 0: 210; while 99999 to 0: 200; for 0 to 99999:
              251
              Test: 3; for 99999 to 0: 210; while 99999 to 0: 200; for 0 to 99999:
              271
              Test: 4; for 99999 to 0: 190; while 99999 to 0: 200; for 0 to 99999:
              241

              While both the decrementing loops are slightly faster then the
              incrementing one (on the order of 50ms over 100000 iterations), there
              is no clear winner between the while() and for() loops.

              Firefox 0.9:

              Test: 0; for 99999 to 0: 371; while 99999 to 0: 340; for 0 to 99999:
              461
              Test: 1; for 99999 to 0: 350; while 99999 to 0: 361; for 0 to 99999:
              451
              Test: 2; for 99999 to 0: 340; while 99999 to 0: 361; for 0 to 99999:
              450
              Test: 3; for 99999 to 0: 351; while 99999 to 0: 350; for 0 to 99999:
              471
              Test: 4; for 99999 to 0: 340; while 99999 to 0: 1913; for 0 to 99999:
              451

              The odd result was where Firefox prompted me that a script was causing
              the browser to run slowly. As with IE, decrementing loops are slightly
              faster.

              Opera 7.51:

              Test: 0; for 99999 to 0: 630; while 99999 to 0: 521; for 0 to 99999:
              741
              Test: 1; for 99999 to 0: 511; while 99999 to 0: 481; for 0 to 99999:
              751
              Test: 2; for 99999 to 0: 501; while 99999 to 0: 480; for 0 to 99999:
              751
              Test: 3; for 99999 to 0: 501; while 99999 to 0: 481; for 0 to 99999:
              751
              Test: 4; for 99999 to 0: 501; while 99999 to 0: 610; for 0 to 99999:
              752

              Similar results.

              Netscape 4.78:

              Test: 0; for 9999 to 0: 58444; while 9999 to 0: 211; for 0 to 9999:
              220
              Test: 1; for 9999 to 0: 180; while 9999 to 0: 171; for 0 to 9999: 220
              Test: 2; for 9999 to 0: 180; while 9999 to 0: 180; for 0 to 9999: 221
              Test: 3; for 9999 to 0: 180; while 9999 to 0: 180; for 0 to 9999: 231
              Test: 4; for 9999 to 0: 180; while 9999 to 0: 8703; for 0 to 9999: 240

              Other then the odd first and second to last values (most likely due to
              garbage collection or some other internal activity), the results are
              pretty much on par with the other browsers listed.

              So optimizing your loops by decrementing instead of incrementing
              achieves an execution speed increase of about 25-50%. That
              optimization time could be better spent elsewhere, such as turning a
              mess like:

              for (var i = 0; i < document.forms['formName'].elements.lengt h; i++) {

              var doSomethingWith =
              document.forms['formName'].elements[i].value;
              }

              into:

              var f = document.forms['formName'].elements;
              for (var i = 0; i < f.length; i++) {
              var doSomethingWith = f[i].value;
              }

              <form name="myForm">
              <input type="text" name="myText" value="">
              <input type="hidden" name="myHidden" value="">
              <input type="radio" name="myRadio" value="">
              <input type="checkbox" name="myCheckbo x" value="">
              <select name="mySelect" >
              <option value="1">one</option>
              </select>
              </form>
              <script type="text/javascript">
              for (var test = 0; test < 5; test++) {
              document.write( 'Test: ' + test + '; ');

              var start = new Date();
              var f = document.forms['myForm'].elements;
              for (var z = 0; z < 100; z++) {
              for (var i = 0; i < f.length; i++) {
              var x = f[i].value;
              }
              }
              document.write( 'cached reference: ' + ((new Date()).getTime () -
              start.getTime() ) + '; ');

              var start = new Date();
              for (var z = 0; z < 100; z++) {
              for (var i = 0; i < document.forms['myForm'].elements.lengt h; i++) {
              var x = document.forms['myForm'].elements[i].value;
              }
              }
              document.write( 'fully qualified: ' + ((new Date()).getTime () -
              start.getTime() ) + '<br>');
              }
              </script>

              Internet Explorer 6SP1:

              Test: 0; cached reference: 50; fully qualified: 171
              Test: 1; cached reference: 50; fully qualified: 180
              Test: 2; cached reference: 50; fully qualified: 180
              Test: 3; cached reference: 40; fully qualified: 181
              Test: 4; cached reference: 50; fully qualified: 180

              The other browsers listed above (with the exception of Netscape 4.78)
              also show an approximate 300-400% increase in speed when accessing
              form elements using a cached reference rather then accessing each
              fully-qualified DOM reference each time. It seems obvious to me where
              a Javascript author's attention should be directed when form
              processing is running slowly.

              --
              | Grant Wagner <gwagner@agrico reunited.com>

              * Client-side Javascript and Netscape 4 DOM Reference available at:
              *


              * Internet Explorer DOM Reference available at:
              *
              Find official documentation, practical know-how, and expert guidance for builders working and troubleshooting in Microsoft products.


              * Netscape 6/7 DOM Reference available at:
              * http://www.mozilla.org/docs/dom/domref/
              * Tips for upgrading JavaScript for Netscape 7 / Mozilla
              * http://www.mozilla.org/docs/web-deve...upgrade_2.html


              Comment

              • Mark Preston

                #8
                Re: Question about performance in IE

                Gui Lloyd wrote:
                [color=blue]
                > I have a problem with performance in IE.
                >[/color]
                Rather than dealing with the specific example, I will just say that
                there are - naturally - differences in speed between IE and any other
                browser. In fact, they are all different in some way.

                Your job as a coder is to be sure that your code actually works, not to
                make it work perfectly and at the same speed on every browser. Quite
                simply, you are not in control of the browsers used for your code or of
                the speed of the browsers either. That is up to (a) the client) and (b)
                the browser developers.

                Comment

                Working...