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 >>