By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,210 Members | 1,033 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,210 IT Pros & Developers. It's quick & easy.

<select>.remove() Performance and Necessity

P: n/a
Hi,

I have read many of the copius entries on the subject of IE performance (or
the lack thereof) when populating Select Lists.

I don't mind the insert performance so much, (I get 100x120byte rows
inserted/sec up to 500, and 100rows/6secs up to 3000, which isn't great but
then the Row Count is clicking away for the user to see and they can hit the
"cancel" button at anytime, so overall I'm happy), what really disappoints
me is the woeful of .REMOVE()!

Before fetching the next result-set I clear down the existing options (I
*do* have to do this don't I?) by looping through option collection calling
remove(1). (Would it be quicker if I removed the last option? Option[0] is a
header.) For 3000 rows this takes an unbelievable 20+secs :-( Does this
sound about right?

1) Is it only IE that performs badly on this?
2) Is there a quicker or more efficient way of zeroing the Select List?
2a) The w3schools ref says the "length" attribute "Returns the number of
options in a dropdown list" it doesn't say "sets Or returns"
2b) The French guy (Stephane?) suggested that I should just set the length
to zero, but wouldn't that result in a memory leak?
3) Do I need to create a malloc/realloc function that keeps a high-water
mark of available option objects for this Drop Down and only "new" some more
options when that's exceeded? (But then the Length would always be off)
4) Use tables and not select lists?
5) Use another browser

Cheers Richard Maher

PS. I changed the .sort(myCompare) from removing/adding to just changing the
..TEXT value and it went from 30secs/3000 rows to ~1sec!
Apr 26 '07 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Richard Maher wrote:
Hi,

I have read many of the copius entries on the subject of IE performance (or
the lack thereof) when populating Select Lists.

I don't mind the insert performance so much, (I get 100x120byte rows
inserted/sec up to 500, and 100rows/6secs up to 3000, which isn't great but
then the Row Count is clicking away for the user to see and they can hit the
"cancel" button at anytime, so overall I'm happy), what really disappoints
me is the woeful of .REMOVE()!
Are you talking about a select element or a table?

Before fetching the next result-set I clear down the existing options (I
*do* have to do this don't I?) by looping through option collection calling
remove(1). (Would it be quicker if I removed the last option? Option[0] is a
header.) For 3000 rows this takes an unbelievable 20+secs :-( Does this
sound about right?
To remove all the options in one go, set the select element's
options.length attribute to zero.

1) Is it only IE that performs badly on this?
Badly at what? Probably the fastest and most cross-browser method to
create option elements is to use:

select.options[i] = new Option(optText, optValue);

2) Is there a quicker or more efficient way of zeroing the Select List?
Set the options collection's length property to zero.

2a) The w3schools ref says the "length" attribute "Returns the number of
options in a dropdown list" it doesn't say "sets Or returns"
w3schools is an OK introduction to javascript, but it is not an
authority and has many errors and instances of bad advice. Read the W3C
specification:

"length of type unsigned long
"This attribute specifies the length or size of the list."

<URL:
http://www.w3.org/TR/DOM-Level-2-HTM...ionsCollection >

2b) The French guy (Stephane?) suggested that I should just set the length
to zero, but wouldn't that result in a memory leak?
Why would it result in a memory leak?

3) Do I need to create a malloc/realloc function that keeps a high-water
mark of available option objects for this Drop Down and only "new" some more
options when that's exceeded? (But then the Length would always be off)
While I don't know what malloc/realloc means to you, but regardless,
there's no such equivalent in javascript. There are no specific
mechanisms for controlling memory allocation.

4) Use tables and not select lists?
They are totally different things.

5) Use another browser
?
--
Rob
Apr 26 '07 #2

P: n/a
Hi Rob,

Thanks for the reply.
Are you talking about a select element or a table?
Select Element.
To remove all the options in one go, set the select element's
options.length attribute to zero.
: : :
>
Set the options collection's length property to zero.
: : :
>
Why would it result in a memory leak?
Why would all of the New Option objects that were instantiated during the
load of the select list suddenly disappear and have their memory freed up by
setting the array length to zero? Maybe it doesn't, but the space/elements
get re-used next time round?

Anyway, I'll take your (and Stephane's) advice and just shrink the array
length. Thanks.

I guess the remove() method is there for when surgical strikes are called
for?
Badly at what? Probably the fastest and most cross-browser method to
create option elements is to use:

select.options[i] = new Option(optText, optValue);
Yep, that's what I'm doing (I'll have to stick in the 2nd parameter to be
x-browser safe) and I'm getting the performance I described for inserts. It
was specifically the REMOVE performance that was giving me grief.

Cheers Richard Maher

"RobG" <rg***@iinet.net.auwrote in message
news:46***********************@per-qv1-newsreader-01.iinet.net.au...
Richard Maher wrote:
Hi,

I have read many of the copius entries on the subject of IE performance
(or
the lack thereof) when populating Select Lists.

I don't mind the insert performance so much, (I get 100x120byte rows
inserted/sec up to 500, and 100rows/6secs up to 3000, which isn't great
but
then the Row Count is clicking away for the user to see and they can hit
the
"cancel" button at anytime, so overall I'm happy), what really
disappoints
me is the woeful of .REMOVE()!

Are you talking about a select element or a table?

Before fetching the next result-set I clear down the existing options (I
*do* have to do this don't I?) by looping through option collection
calling
remove(1). (Would it be quicker if I removed the last option? Option[0]
is a
header.) For 3000 rows this takes an unbelievable 20+secs :-( Does this
sound about right?

To remove all the options in one go, set the select element's
options.length attribute to zero.

1) Is it only IE that performs badly on this?

Badly at what? Probably the fastest and most cross-browser method to
create option elements is to use:

select.options[i] = new Option(optText, optValue);

2) Is there a quicker or more efficient way of zeroing the Select List?

Set the options collection's length property to zero.

2a) The w3schools ref says the "length" attribute "Returns the number of
options in a dropdown list" it doesn't say "sets Or returns"

w3schools is an OK introduction to javascript, but it is not an
authority and has many errors and instances of bad advice. Read the W3C
specification:

"length of type unsigned long
"This attribute specifies the length or size of the list."

<URL:
http://www.w3.org/TR/DOM-Level-2-HTM...ionsCollection >

2b) The French guy (Stephane?) suggested that I should just set the
length
to zero, but wouldn't that result in a memory leak?

Why would it result in a memory leak?

3) Do I need to create a malloc/realloc function that keeps a high-water
mark of available option objects for this Drop Down and only "new" some
more
options when that's exceeded? (But then the Length would always be off)

While I don't know what malloc/realloc means to you, but regardless,
there's no such equivalent in javascript. There are no specific
mechanisms for controlling memory allocation.

4) Use tables and not select lists?

They are totally different things.

5) Use another browser

?
--
Rob

Apr 26 '07 #3

P: n/a
Hi Again,
Anyway, I'll take your (and Stephane's) advice and just shrink the array
length. Thanks.
Ok I did that and I'm now more confident that there won't be a memory leak
'cos the performance is still as crap as when I was explicitly calling
..remove()

If I currently have 3000x120byte rows in the selectList then it takes
~24secs to set the length to zero (or to "one" in my case with a "header"
row) before it starts re-populating the select list with the next result
set. (And then about 1min10secs to repopulate it)

Can someone manage my expectations here on what "reasonable" performance
should be with Select Lists?

The strange (at least to me) thing is that is CPU bound and doesn't appear
to be a memory issue at all. The page shows 100% cpu while it's deallocating
and then a short break until the server has primed the socket with data and
then it's 100% straight until the last row is inserted. Memory usage doesn't
seen to budge. (That's a shit load of CPU for the Mickey Mouse work we're
talking about!)

This has gotta be pilot error surely? Are there some obvious IE or Windows
tuning parameters that I should look at?

Once again, I am setTimeout(getNextRecord,0) as a loop control so that the
Record Count clicks over and the screen gets updated. But clearly that
shouldn't effect the "Free" processing. I'll give it a go at setting the
length to zero instead of one to see if that makes a difference.

Cheers Richard Maher

BTW. It's a Pentium 1300MHz Laptop running Windows2000 and IE6
"Richard Maher" <ma******@hotspamnotmail.comwrote in message
news:f0**********@news-01.bur.connect.com.au...
Hi Rob,

Thanks for the reply.
Are you talking about a select element or a table?

Select Element.
To remove all the options in one go, set the select element's
options.length attribute to zero.
: : :

Set the options collection's length property to zero.
: : :

Why would it result in a memory leak?

Why would all of the New Option objects that were instantiated during the
load of the select list suddenly disappear and have their memory freed up
by
setting the array length to zero? Maybe it doesn't, but the space/elements
get re-used next time round?

Anyway, I'll take your (and Stephane's) advice and just shrink the array
length. Thanks.

I guess the remove() method is there for when surgical strikes are called
for?
Badly at what? Probably the fastest and most cross-browser method to
create option elements is to use:

select.options[i] = new Option(optText, optValue);

Yep, that's what I'm doing (I'll have to stick in the 2nd parameter to be
x-browser safe) and I'm getting the performance I described for inserts.
It
was specifically the REMOVE performance that was giving me grief.

Cheers Richard Maher

"RobG" <rg***@iinet.net.auwrote in message
news:46***********************@per-qv1-newsreader-01.iinet.net.au...
Richard Maher wrote:
Hi,
>
I have read many of the copius entries on the subject of IE
performance
(or
the lack thereof) when populating Select Lists.
>
I don't mind the insert performance so much, (I get 100x120byte rows
inserted/sec up to 500, and 100rows/6secs up to 3000, which isn't
great
but
then the Row Count is clicking away for the user to see and they can
hit
the
"cancel" button at anytime, so overall I'm happy), what really
disappoints
me is the woeful of .REMOVE()!
Are you talking about a select element or a table?

Before fetching the next result-set I clear down the existing options
(I
*do* have to do this don't I?) by looping through option collection
calling
remove(1). (Would it be quicker if I removed the last option?
Option[0]
is a
header.) For 3000 rows this takes an unbelievable 20+secs :-( Does
this
sound about right?
To remove all the options in one go, set the select element's
options.length attribute to zero.

1) Is it only IE that performs badly on this?
Badly at what? Probably the fastest and most cross-browser method to
create option elements is to use:

select.options[i] = new Option(optText, optValue);

2) Is there a quicker or more efficient way of zeroing the Select
List?

Set the options collection's length property to zero.

2a) The w3schools ref says the "length" attribute "Returns the number
of
options in a dropdown list" it doesn't say "sets Or returns"
w3schools is an OK introduction to javascript, but it is not an
authority and has many errors and instances of bad advice. Read the W3C
specification:

"length of type unsigned long
"This attribute specifies the length or size of the list."

<URL:
http://www.w3.org/TR/DOM-Level-2-HTM...ionsCollection >

2b) The French guy (Stephane?) suggested that I should just set the
length
to zero, but wouldn't that result in a memory leak?
Why would it result in a memory leak?

3) Do I need to create a malloc/realloc function that keeps a
high-water
mark of available option objects for this Drop Down and only "new"
some
more
options when that's exceeded? (But then the Length would always be
off)

While I don't know what malloc/realloc means to you, but regardless,
there's no such equivalent in javascript. There are no specific
mechanisms for controlling memory allocation.

4) Use tables and not select lists?
They are totally different things.

5) Use another browser
?
--
Rob


Apr 27 '07 #4

P: n/a
On Apr 27, 4:18 pm, "Richard Maher" <maher...@hotspamnotmail.com>
wrote:
Hi Again,
Please trim the bits you aren't replying to.

Anyway, I'll take your (and Stephane's) advice and just shrink the array
length. Thanks.

Ok I did that and I'm now more confident that there won't be a memory leak
'cos the performance is still as crap as when I was explicitly calling
.remove()

If I currently have 3000x120byte rows in the selectList then it takes
You mean 3,000 option elements? Do you really want to do that?
~24secs to set the length to zero (or to "one" in my case with a "header"
row) before it starts re-populating the select list with the next result
set. (And then about 1min10secs to repopulate it)
I can't test IE right now, but for a select with 3,000 options,
setting options.length = 0 in Safari takes about 320ms, Firefox 120ms,
Opera 160ms on an iBook 2GHz Core2Duo. Some test code is below.

Can someone manage my expectations here on what "reasonable" performance
should be with Select Lists?
Adding 3,000 options takes Safari 750ms, Firefox 220ms and Opera
530ms.
>
The strange (at least to me) thing is that is CPU bound and doesn't appear
to be a memory issue at all. The page shows 100% cpu while it's deallocating
and then a short break until the server has primed the socket with data and
then it's 100% straight until the last row is inserted. Memory usage doesn't
seen to budge. (That's a shit load of CPU for the Mickey Mouse work we're
talking about!)
Ask MS to fix their browser.
>
This has gotta be pilot error surely? Are there some obvious IE or Windows
tuning parameters that I should look at?
Ditch IE?
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<title>Options play</title>
<script type="text/javascript">

function removeOptions(f){
var s = new Date();
f.sel0.options.length = 0;
document.getElementById('xx').innerHTML = (new Date() - s)+'ms';
}

function addOptions(f){
var sel = f.sel0;
var s = new Date();
for (var i=0; i<3000; i++) {
sel.options[i] = new Option(i, i);
}
document.getElementById('xx').innerHTML = (new Date() - s)+'ms';
}

</script>

<form name="country"><div>
<input type="button" onclick="removeOptions(this.form)"
value="Remove options">
<input type="button" onclick="addOptions(this.form)"
value="Add options"><br>
<select name="sel0">
<script type="text/javascript">
var t = [];
for (var i=0; i<3000; i++){
t.push('<option>' + i);
}
document.write(t.join(''));
</script>
</select>
</div></form>
<div>Time taken: <span id="xx"></span></div>
--
Rob

Apr 27 '07 #5

P: n/a
On Apr 27, 7:54 pm, RobG <r...@iinet.net.auwrote:
On Apr 27, 4:18 pm, "Richard Maher" <maher...@hotspamnotmail.com>
[...]
This has gotta be pilot error surely? Are there some obvious IE or Windows
tuning parameters that I should look at?

Ditch IE?
Something you might try is replacing the select with a shallow clone
of itself - test widely, it may not be well supported by older
browsers:

function removeOptions2(f){
var sel = f.elements['sel0'];
var oSel = sel.cloneNode(false);
oSel.options[0] = new Option('New option');
sel.parentNode.replaceChild(oSel, sel);
}
Note that a select with no options is invalid HTML. Times in browses
reported previously are: 57ms, 14ms and 7ms respectively.
--
Rob

Apr 27 '07 #6

P: n/a
Hi Rob

RobG wrote:
You mean 3,000 option elements? Do you really want to do that?
I have only recently stumbled across the school of thought that says
JavaScript and HTML are more than capable of providing the functionality and
performance needed for a complete browser-based application GUI, so I
thought it was time that I educated myself a little bit about the potential
of these tools. To that end I've built a proof-of-concept example, one part
of which is the loading a database-query result-set into a scrolling list.
Now, I imagine 99% of the time we'd be talking 10s to low 100s of matching
rows, but I don't think 3000 is ridiculous or out of the realms of
possibility. (Especially as the user is empowered (by the hot abort button)
to terminate the query at any time, if they so choose. The "All transactions
between a certain date range" scenario.)
Adding 3,000 options takes Safari 750ms, Firefox 220ms and Opera
530ms.
Thanks for the example code and real figures. I know I should've done that.

Your code on my box takes 20910ms to add 3K and 4907ms to remove them :-(

The second and subsequent times the "add" consistently took ~5600ms and the
"remove" stayed at 4860ms.

Does anyone else have IE7 that they can run Rob's code on to check?
Ask MS to fix their browser.
: : : :
Ditch IE?
Certainly looks the way to go. What could it possibly be doing with all that
CPU? Bitmap or hash algorithm for *every* free byte in memory?

Ok, going forward, can I run FireFox on my Windows2000 box and have it
co-exists happily with IE? (IE in one window, FF in another?)

Cheers Richard Maher
Apr 28 '07 #7

P: n/a
Rob G you are an absolute bloody champion!
Something you might try is replacing the select with a shallow clone
of itself - test widely, it may not be well supported by older
browsers:

function removeOptions2(f){
var sel = f.elements['sel0'];
var oSel = sel.cloneNode(false);
oSel.options[0] = new Option('New option');
sel.parentNode.replaceChild(oSel, sel);
}
20ms is all it takes (Now I have to see if I can get it to work with my
code. "Why should it be any different?" you ask, well maybe I'm just being a
worry wart but I've had sooo much trouble with turning off selectedIndex and
then if there's only one option (my header row) then sometimes it's blank
and then you click the down arrow the option appears there, and flickering,
and I've left the size at 2 for another select list even if the length is
only 1 just so it doesn't stuff up the screen and and and who cares?)

Given the problem statement you played a blinder! Thanks again.

Cheers Richard Maher

PS. Where does one find the documentation for all these replaceChild and
appendChild methods?

"RobG" <rg***@iinet.net.auwrote in message
news:11**********************@r30g2000prh.googlegr oups.com...
On Apr 27, 7:54 pm, RobG <r...@iinet.net.auwrote:
On Apr 27, 4:18 pm, "Richard Maher" <maher...@hotspamnotmail.com>
[...]
This has gotta be pilot error surely? Are there some obvious IE or
Windows
tuning parameters that I should look at?
Ditch IE?

Something you might try is replacing the select with a shallow clone
of itself - test widely, it may not be well supported by older
browsers:

function removeOptions2(f){
var sel = f.elements['sel0'];
var oSel = sel.cloneNode(false);
oSel.options[0] = new Option('New option');
sel.parentNode.replaceChild(oSel, sel);
}
Note that a select with no options is invalid HTML. Times in browses
reported previously are: 57ms, 14ms and 7ms respectively.
--
Rob

Apr 28 '07 #8

P: n/a
On Apr 27, 7:13 pm, "Richard Maher" <maher...@hotspamnotmail.com>
wrote:
Where does one find the documentation for all these replaceChild and
appendChild methods?
http://developer.mozilla.org/en/docs/DOM:element

http://developer.mozilla.org/en/docs/DOM:window

http://developer.mozilla.org/en/docs/DOM:document

http://developer.mozilla.org/en/docs/DOM:event

http://msdn2.microsoft.com/en-us/library/ms533053.aspx

Apr 28 '07 #9

P: n/a
Hi,

Thanks for the references.
["scripts.contact" Gave me several usefule web references]

Related to Rob's solution of a shallow clone of the SelectList node, can
someone advise me of a better way to preserve the "header" row(s) contents
and attributes across versions of the Select Nodes? This is what I'm doing
now: -

selectRef.size = 1;
selectClone = selectRef.cloneNode(false);
lovHdr = document.getElementById('lovHdr');
hdrClone = lovHdr.cloneNode(true);
selectClone.appendChild(hdrClone);
selectRef.parentNode.replaceChild(selectClone, selectRef);
selectRef = document.getJobs.jobList;

I could (like Rob's example) just recreate the header entry each time with a
"new Option ('my header')" but I was rather hoping to just have a template
Node (for a blank SelectList with nothing but its option[0] header and all
its child nodes) sitting there that could be redeployed when needed.

Am I correct in thinking that each clone is consumed by the replaceChild()
so the cloneNode() has to happen anyway? And if I try to create a clone at
page-load time (then do a clone of that clone at replace-time) then I'm
going to run into trouble with ElementIds between the real selectList and
the dummy-template clone?

Anyway, who cares? I like it the way it is. Thanks again for the help - the
performance is great!

Cheers Richard Maher

"scripts.contact" <sc*************@gmail.comwrote in message
news:11**********************@l77g2000hsb.googlegr oups.com...
On Apr 27, 7:13 pm, "Richard Maher" <maher...@hotspamnotmail.com>
wrote:
Where does one find the documentation for all these replaceChild and
appendChild methods?

http://developer.mozilla.org/en/docs/DOM:element

http://developer.mozilla.org/en/docs/DOM:window

http://developer.mozilla.org/en/docs/DOM:document

http://developer.mozilla.org/en/docs/DOM:event

http://msdn2.microsoft.com/en-us/library/ms533053.aspx

Apr 30 '07 #10

P: n/a
On Apr 30, 2:28 pm, "Richard Maher" <maher...@hotspamnotmail.com>
wrote:
Hi,
Please don't top-post, reply below trimmed quotes.

Thanks for the references.
["scripts.contact" Gave me several usefule web references]

Related to Rob's solution of a shallow clone of the SelectList node, can
someone advise me of a better way to preserve the "header" row(s) contents
and attributes across versions of the Select Nodes? This is what I'm doing
now: -

selectRef.size = 1;
selectClone = selectRef.cloneNode(false);
lovHdr = document.getElementById('lovHdr');
hdrClone = lovHdr.cloneNode(true);
selectClone.appendChild(hdrClone);
The above two lines could be:

selectClone.appendChild(lovHdr.cloneNode(true));

selectRef.parentNode.replaceChild(selectClone, selectRef);
selectRef = document.getJobs.jobList;

I could (like Rob's example) just recreate the header entry each time with a
"new Option ('my header')" but I was rather hoping to just have a template
Node (for a blank SelectList with nothing but its option[0] header and all
its child nodes) sitting there that could be redeployed when needed.
Why just clone the option? Why not clone the whole "template" select,
modify the attribute appropriately and replace the one that's there?

Am I correct in thinking that each clone is consumed by the replaceChild()
so the cloneNode() has to happen anyway?
Consumed? When you clone an element, you create a new object. If you
want to have say six new objects (in this case, DOM HTML select
elements), you have to make six clones.
And if I try to create a clone at
page-load time (then do a clone of that clone at replace-time) then I'm
going to run into trouble with ElementIds between the real selectList and
the dummy-template clone?
As long as the template clone isn't added to the DOM (say using
appendChild) you're OK. document.getElementById only searches the
DOM, it has no idea what you are holding references to elsewhere (or
at least it shouldn't - if it does it's a bug).

A simple test:

<div id="xx"></div>

<script type="text/javascript">
var x = document.getElementById('xx');
var y = x.cloneNode(true);
x.parentNode.removeChild(x);
alert(document.getElementById('xx') +
'\n' + y + ' id: ' + y.id);
</script>

In IE and Firefox, div xx is removed from the document, getElementById
can't find the clone.

--
Rob

Apr 30 '07 #11

P: n/a
Hi Rob,
As long as the template clone isn't added to the DOM (say using
appendChild) you're OK. document.getElementById only searches the
DOM, it has no idea what you are holding references to elsewhere (or
at least it shouldn't - if it does it's a bug).
That's the bit I wasn't sure of. Sounds great; I'll give it a go.

Cheers Richard Maher
Apr 30 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.