Reputation: 730
Is there a way to make the following code faster? It's becoming too slow, when length of array is more than 1000 records, especially in IE6.
dbusers = data.split(";");
$("#users").html("");
for (i = 0; i < dbusers.length; i++) {
if ($("#username").val() != "") {
if (dbusers[i].indexOf($("#username").val()) != -1) {
$("#users").append(dbusers[i] + "<br>");
}
} else {
$("#users").append(dbusers[i] + "<br>");
}
}
Upvotes: 2
Views: 333
Reputation: 344567
IE6 doesn't support querySelector
, so lookups can be particularly slow. Keep HTML manipulation within loops to a minimum by reducing the number of appends you do, each one has a regular expression run on it to extract the HTML and convert it to a DOM object. Also work in some micro optimisations where you can, might improve performance a little especially over thousands of iterations.
var usersEl = $("#users"); // reduce lookups to the #users element
var result = ""; // create a variable for the HTML string
var unameVal = $("#username").val(); // do the username value lookup only once
dbusers = data.split(";");
usersEl.html("");
// Store the length of the array in a var in your loop to prevent multiple lookups
for (var i = 0, max = dbusers.length; i < max; i++) {
if (unameVal !== "") {
if (dbusers[i].indexOf(unameVal) != -1) {
result += dbusers[i] + "<br>";
}
} else {
result += dbusers[i] + "<br>";
}
}
usersEl.html(result); // Set the HTML only once, saves multiple regexes
Upvotes: 1
Reputation: 90012
Use a document fragment.
You can perform more optimizations, too, like removing that nasty if and creating the nodes yourself.
var frag = document.createDocumentFragment(),
dbUsers = data.split(';'),
dbUsersLength = dbUsers.length,
curDbUser,
usernameVal = $('#username').val();
for(i = 0; i < dbUsersLength; ++i) {
curDbUser = dbUsers[i];
if(curDbUser.indexOf(usernameVal) !== -1) {
frag.appendChild(document.createTextNode(curDbUser));
frag.appendChild(document.createElement('br'));
}
}
$('#users').empty().append(frag);
I made a tool to benchmark all the current answers: http://dev.liranuna.com/strager/stee1rat.html
ghoppe's and mine seem to be the fastest.
Upvotes: 2
Reputation: 413709
Faster than those by far (especially in IE!) is to build your string as an array (yes, really) and then concatenate it at the end:
var dbusers = data.split(";"), username = $('#username').val();
$("#users").html($.map(dbusers, function(_, dbuser) {
if (username == '' || dbuser.indexOf(username) > 0)
return dbuser + '<br>';
return '';
}).get().join(''));
The $.map()
routine will build an array from the return values of the function you pass. Here, my function is returning the user string followed by the <br>
. The resulting array is then turned into a string by calling the native join()
routine. Especially when you've got like 1000 things to work with, this will be much faster than building a string with repeated calls to +=
! Try the two versions and compare!
Upvotes: 2
Reputation: 21784
Minimize the amount of work you do in the loop. Don't add stuff to the DOM in the loop, create a string.
var dbusers = data.split(";");
var username = $("#username").val();
var userlist = "";
if (username == "") {
for (i = 0; i < dbusers.length; i++) {
userlist += dbusers[i] + "<br>";
}
} else {
for (i = 0; i < dbusers.length; i++) {
if (dbusers[i].indexOf(username) != -1) {
userlist += dbusers[i] + "<br>";
}
}
}
$("#users").html(userlist);
Upvotes: 5