Hi All,
I am currently using script.aculo.us and Autocompleter for a project which I
am dealing now. I
faced a situation for which I couldnt find any solution and I could not see
any reference
regarding this issue in the enhancement/bug lists of script.aculo.us either.
Autocompleter component is working perfectly, if the information returned
from the server
does not exceed ~1000 LIs. (Autocompleter is receiving an UL full of LIs) I
know that it
is not a common scenario for an AutoCompleter to handle 1000 results but
this is in my
case needed and I have to make AutoCompleter function in such a case. In the
result
div I use the vertical scrolling.(Otherwise I would not be able to show 1000
results)
I have identified couple of places in the code which can be bottlenecks, I
would be glad
if you guys could comment about it. (code snips are from control.js latest
released version)
<code snip>
render: function() {
if(this.entryCount > 0) {
for (var i = 0; i < this.entryCount; i++)
this.index==i ?
Element.addClassName(this.getEntry(i),"selected") :
Element.removeClassName(this.getEntry(i),"selected");
if(this.hasFocus) {
this.show();
this.active = true;
}
} else {
this.active = false;
this.hide();
}
}
</code snip>
The render function above is running into a for loop in order to
make the "Highlighting" effect work. (onHover calls this function)
When you have 1000 items in the list and just move the mouse
over the list, onHover gets called several times and enters the
for loop which will iterate 1000 times for each call. IE and the
javascript engine goes crazy and memory consumption of IE
increases. I have commented out this part, as I can live without
the "Highlighting" effect. But this part is in my opinion not that
scalable and may need improvement.
<code snip>
updateChoices: function(choices) {
if(!this.changed && this.hasFocus) {
this.update.innerHTML = choices;
Element.cleanWhitespace(this.update);
Element.cleanWhitespace(this.update.firstChild);
if(this.update.firstChild && this.update.firstChild.childNodes) {
this.entryCount this.update.firstChild.childNodes.length;
for (var i = 0; i < this.entryCount; i++) {
var entry = this.getEntry(i);
entry.autocompleteIndex = i;
this.addObservers(entry);
}
} else {
this.entryCount = 0;
}
this.stopIndicator();
this.index = 0;
this.render();
}
}
</code snip>
And this code above is called after the ajax callback is called with
UL list. There are two calls to Element.CleanWhiteSpace. Second
call ends up in a for loop in the Prototype library which is an expensive
operation.(I have commented out this part as well, as I can make sure that
there are no whitespaces
in the list delivered by the server) And the for-loop above adds an
individual listener for EACH LI item. For 1000 LI, it will add 1000
listeners
and this may take minutes. This is really an expensive operation. But I can
not comment
out this part, as without listeners the clicks on LIs will not function
which makes the Autocompleter
useless. I have a rough idea of delivering "onClick" events hard-coded
from the server side as part of the UL list but I am not sure whether
this solution feasible is.
I would be glad, if you guys could share your opinions regarding the issues
mentioned
above. I guess we have some room for improvement of AutoCompleter and the
scalability
of the component can also get better but this may need some design changes
of the
whole AutoCompleter component.
Thanks & Regards
Guvenc Gulce
_______________________________________________
Rails-spinoffs mailing list
Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
For any large chunks of data, it is far better to let the server do the
processing rather than try to make the client stitch together 1000s of
DOM elements (and then expect it to be fast)....
You need to have the server build the HTML string to return and simply
have the client do a single $(myElement).innerHTML = theResponse;
Now, I don''t use the AutoCompleter, but if it doesn''t support
this
method of handling responses, you might want to use your own widget
instead.
________________________________
From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
[mailto:rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org]
On Behalf Of
Guvenc Gulce
Sent: Monday, January 23, 2006 10:47 AM
To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
Subject: [Rails-spinoffs] Performance Issues with Autocompleter
Hi All,
I am currently using script.aculo.us and Autocompleter for a project
which I am dealing now. I
faced a situation for which I couldnt find any solution and I could not
see any reference
regarding this issue in the enhancement/bug lists of script.aculo.us
either.
Autocompleter component is working perfectly, if the information
returned from the server
does not exceed ~1000 LIs. (Autocompleter is receiving an UL full of
LIs) I know that it
is not a common scenario for an AutoCompleter to handle 1000 results but
this is in my
case needed and I have to make AutoCompleter function in such a case. In
the result
div I use the vertical scrolling.(Otherwise I would not be able to show
1000 results)
I have identified couple of places in the code which can be bottlenecks,
I would be glad
if you guys could comment about it. (code snips are from control.js
latest released version)
<code snip>
render: function() {
if(this.entryCount > 0) {
for (var i = 0; i < this.entryCount; i++)
this.index==i ?
Element.addClassName(this.getEntry(i),"selected") :
Element.removeClassName(this.getEntry(i),"selected");
if(this.hasFocus) {
this.show();
this.active = true;
}
} else {
this.active = false;
this.hide();
}
}
</code snip>
The render function above is running into a for loop in order to
make the "Highlighting" effect work. (onHover calls this function)
When you have 1000 items in the list and just move the mouse
over the list, onHover gets called several times and enters the
for loop which will iterate 1000 times for each call. IE and the
javascript engine goes crazy and memory consumption of IE
increases. I have commented out this part, as I can live without
the "Highlighting" effect. But this part is in my opinion not that
scalable and may need improvement.
<code snip>
updateChoices: function(choices) {
if(!this.changed && this.hasFocus ) {
this.update.innerHTML = choices;
Element.cleanWhitespace(this.update);
Element.cleanWhitespace(this.update.firstChild);
if(this.update.firstChild && this.update.firstChild.childNodes ) {
this.entryCount =
this.update.firstChild.childNodes.length;
for (var i = 0; i < this.entryCount; i++) {
var entry = this.getEntry(i);
entry.autocompleteIndex = i;
this.addObservers(entry);
}
} else {
this.entryCount = 0;
}
this.stopIndicator();
this.index = 0;
this.render();
}
}
</code snip>
And this code above is called after the ajax callback is called with
UL list. There are two calls to Element.CleanWhiteSpace. Second
call ends up in a for loop in the Prototype library which is an
expensive
operation.(I have commented out this part as well, as I can make sure
that there are no whitespaces
in the list delivered by the server) And the for-loop above adds an
individual listener for EACH LI item. For 1000 LI, it will add 1000
listeners
and this may take minutes. This is really an expensive operation. But I
can not comment
out this part, as without listeners the clicks on LIs will not function
which makes the Autocompleter
useless. I have a rough idea of delivering "onClick" events hard-coded
from the server side as part of the UL list but I am not sure whether
this solution feasible is.
I would be glad, if you guys could share your opinions regarding the
issues mentioned
above. I guess we have some room for improvement of AutoCompleter and
the scalability
of the component can also get better but this may need some design
changes of the
whole AutoCompleter component.
Thanks & Regards
Guvenc Gulce
The information transmitted in this electronic mail is intended only for the
person or entity to which it is addressed and may contain confidential,
proprietary, and/or privileged material. Any review, retransmission,
dissemination or other use of, or taking of any action in reliance upon,
this information by persons or entities other than the intended recipient
is prohibited. If you received this in error, please contact the sender and
delete the material from all computers.
_______________________________________________
Rails-spinoffs mailing list
Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
Ryan, It does use this method. The problem is that it also loops through those created DOM elements to add event handlers (so you can key through the results, click on them, etc.). Cam. On 1/23/06, Ryan Gahl <Ryan.Gahl@camtronics.com> wrote:> > Now, I don't use the AutoCompleter, but if it doesn't support this method of > handling responses, you might want to use your own widget instead._______________________________________________ Rails-spinoffs mailing list Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
Ok, in that case, perform as much of the event handler attachment asynchronously as you can. Wrap the entire event handler attachment process into one function which gets kicked off in a setTimeout with 1 millisecond delay... and each attachment itself in another setTimeout. You may only gain a small performance increase from this, but then again it may be huge. Anything that does not need to be executed in a specific order is a candidate for asynchronous execution. As for memory, yea, attaching 1000 event handlers is going to take up memory (thus slowing the whole document down). No way around it. -----Original Message----- From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Cam McVey Sent: Monday, January 23, 2006 11:03 AM To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: Re: [Rails-spinoffs] Performance Issues with Autocompleter Ryan, It does use this method. The problem is that it also loops through those created DOM elements to add event handlers (so you can key through the results, click on them, etc.). Cam. On 1/23/06, Ryan Gahl <Ryan.Gahl-nlycWCgr5/vuufBYgWm87A@public.gmane.org> wrote:> > Now, I don''t use the AutoCompleter, but if it doesn''t support thismethod of> handling responses, you might want to use your own widget instead.The information transmitted in this electronic mail is intended only for the person or entity to which it is addressed and may contain confidential, proprietary, and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from all computers.
Or... if you''re really desparate I guess you could make the server hard-code the event handlers inline in each element in the returned HTML. That would at least save the looping, but it''s not ideal obviously. -----Original Message----- From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Ryan Gahl Sent: Monday, January 23, 2006 11:34 AM To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: RE: [Rails-spinoffs] Performance Issues with Autocompleter Ok, in that case, perform as much of the event handler attachment asynchronously as you can. Wrap the entire event handler attachment process into one function which gets kicked off in a setTimeout with 1 millisecond delay... and each attachment itself in another setTimeout. You may only gain a small performance increase from this, but then again it may be huge. Anything that does not need to be executed in a specific order is a candidate for asynchronous execution. As for memory, yea, attaching 1000 event handlers is going to take up memory (thus slowing the whole document down). No way around it. -----Original Message----- From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Cam McVey Sent: Monday, January 23, 2006 11:03 AM To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: Re: [Rails-spinoffs] Performance Issues with Autocompleter Ryan, It does use this method. The problem is that it also loops through those created DOM elements to add event handlers (so you can key through the results, click on them, etc.). Cam. On 1/23/06, Ryan Gahl <Ryan.Gahl-nlycWCgr5/vuufBYgWm87A@public.gmane.org> wrote:> > Now, I don''t use the AutoCompleter, but if it doesn''t support thismethod of> handling responses, you might want to use your own widget instead.The information transmitted in this electronic mail is intended only for the person or entity to which it is addressed and may contain confidential, proprietary, and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from all computers. _______________________________________________ Rails-spinoffs mailing list Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
Heya, As you said, it''s certainly not a common use case for an autocompleting textbox to have 1000s of suggestions. The Autocompleter is supposed to return anything from 1 to 10 completions. If you need to support more than that, you have to come up with a modified version, probably involving using only one event listener and either do a find-out-the-element-by-mouse-position thing or some trickery with bubbling events. -Thomas Am 23.01.2006 um 17:46 schrieb Guvenc Gulce:> Hi All, > I am currently using script.aculo.us and Autocompleter for a > project which I am dealing now. I > faced a situation for which I couldnt find any solution and I could > not see any reference > regarding this issue in the enhancement/bug lists of > script.aculo.us either. > > Autocompleter component is working perfectly, if the information > returned from the server > does not exceed ~1000 LIs. (Autocompleter is receiving an UL full > of LIs) I know that it > is not a common scenario for an AutoCompleter to handle 1000 > results but this is in my > case needed and I have to make AutoCompleter function in such a > case. In the result > div I use the vertical scrolling.(Otherwise I would not be able to > show 1000 results) > > I have identified couple of places in the code which can be > bottlenecks, I would be glad > if you guys could comment about it. (code snips are from control.js > latest released version) > > <code snip> > render: function() { > if(this.entryCount > 0) { > for (var i = 0; i < this.entryCount; i++) > this.index==i ? > Element.addClassName(this.getEntry(i),"selected") : > Element.removeClassName(this.getEntry(i),"selected"); > > if(this.hasFocus) { > this.show(); > this.active = true; > } > } else { > this.active = false; > this.hide(); > } > } > </code snip> > > > The render function above is running into a for loop in order to > make the "Highlighting" effect work. (onHover calls this function) > When you have 1000 items in the list and just move the mouse > over the list, onHover gets called several times and enters the > for loop which will iterate 1000 times for each call. IE and the > javascript engine goes crazy and memory consumption of IE > increases. I have commented out this part, as I can live without > the "Highlighting" effect. But this part is in my opinion not that > scalable and may need improvement. > > <code snip> > updateChoices: function(choices) { > if(!this.changed && this.hasFocus ) { > this.update.innerHTML = choices; > Element.cleanWhitespace(this.update); > Element.cleanWhitespace(this.update.firstChild); > > if(this.update.firstChild && > this.update.firstChild.childNodes ) { > this.entryCount > this.update.firstChild.childNodes.length; > for (var i = 0; i < this.entryCount; i++) { > var entry = this.getEntry(i); > entry.autocompleteIndex = i; > this.addObservers(entry); > } > } else { > this.entryCount = 0; > } > > this.stopIndicator(); > > this.index = 0; > this.render(); > } > } > </code snip> > > And this code above is called after the ajax callback is called with > UL list. There are two calls to Element.CleanWhiteSpace. Second > call ends up in a for loop in the Prototype library which is an > expensive > operation.(I have commented out this part as well, as I can make > sure that there are no whitespaces > in the list delivered by the server) And the for-loop above adds an > individual listener for EACH LI item. For 1000 LI, it will add 1000 > listeners > and this may take minutes. This is really an expensive operation. > But I can not comment > out this part, as without listeners the clicks on LIs will not > function which makes the Autocompleter > useless. I have a rough idea of delivering "onClick" events hard-coded > from the server side as part of the UL list but I am not sure whether > this solution feasible is. > > I would be glad, if you guys could share your opinions regarding > the issues mentioned > above. I guess we have some room for improvement of AutoCompleter > and the scalability > of the component can also get better but this may need some design > changes of the > whole AutoCompleter component. > > Thanks & Regards > > Guvenc Gulce > _______________________________________________ > Rails-spinoffs mailing list > Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs_______________________________________________ Rails-spinoffs mailing list Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
I have the same problem. My Solution? more filter on query and limit results to ~50, so you always get max 50 results and if you type more about the world, the result is more exactly. PS: sorry my bad english :P Cam McVey escreveu:> Ryan, > > It does use this method. The problem is that it also loops through > those created DOM elements to add event handlers (so you can key > through the results, click on them, etc.). > > Cam. > > > On 1/23/06, Ryan Gahl <Ryan.Gahl-nlycWCgr5/vuufBYgWm87A@public.gmane.org> wrote: > >> Now, I don''t use the AutoCompleter, but if it doesn''t support this method of >> handling responses, you might want to use your own widget instead. >> >> ------------------------------------------------------------------------ >> >> _______________________________________________ >> Rails-spinoffs mailing list >> Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org >> http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs >>