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 [email protected] http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
