title: Optimizing JS Array Search
body: <p>I am working on a Browser-based media player which is written almost entirely in HTML 5 and JavaScript. The backend is written in PHP but it has one function which is to fill the playlist on the initial load. And the rest is all JS. There is a search bar that refines the playlist. I want it to refine as the person is typing, like most media players do. The only problem with this is that it is very slow and laggy as there are about 1000 songs in the whole program and there is likely to be more as time goes on.</p>
  
  <p>The original playlist load is an ajax call to a PHP page that returns the results as JSON. Each item has 4 attirbutes:</p>
  
  <ol>
  <li>artist</li>
  <li>album</li>
  <li>file</li>
  <li>url</li>
  </ol>
  
  <p>I then loop through each object and add it to an array called <code>playlist</code>. At the end of the looping a copy of <code>playlist</code> is created, <code>backup</code>. This is so that I can refine the <code>playlist</code> variable when people refine their search, but still repopulated it from <code>backup</code> without making another server request.</p>
  
  <p>The method <code>refine()</code> is called when the user types a key into the searchbox. It flushes <code>playlist</code> and searches through each property (not including <code>url</code>) of each object in the <code>backup</code> array for a match in the string. If there is a match in any of the properties, it appends the information to a table that displays the playlist, and adds it to the object to <code>playlist</code> for access by the actual player. </p>
  
  <p>Code for the <code>refine()</code> method:</p>
  
  <pre><code>function refine() {
      $('#loadinggif').show();
      $('#library').html("&lt;table id='libtable'&gt;&lt;tr&gt;&lt;th&gt;Artist&lt;/th&gt;&lt;th&gt;Album&lt;/th&gt;&lt;th&gt;File&lt;/th&gt;&lt;th&gt;&amp;nbsp;&lt;/th&gt;&lt;/tr&gt;&lt;/table&gt;");
      playlist = [];
      for (var j = 0; j &lt; backup.length; j++) {
          var sfile = new String(backup[j].file);
          var salbum = new String(backup[j].album);
          var sartist = new String(backup[j].artist);
          if (sfile.toLowerCase().search($('#search').val().toLowerCase()) !== -1 || salbum.toLowerCase().search($('#search').val().toLowerCase()) !== -1 || sartist.toLowerCase().search($('#search').val().toLowerCase()) !== -1) {
              playlist.push(backup[j]);
              num = playlist.length-1;
              $("&lt;tr&gt;&lt;/tr&gt;").html("&lt;td&gt;" + num + "&lt;/td&gt;&lt;td&gt;" + sartist + "&lt;/td&gt;&lt;td&gt;" + salbum + "&lt;/td&gt;&lt;td&gt;" + sfile + "&lt;/td&gt;&lt;td&gt;&lt;a href='#' onclick='setplay(" + num +");'&gt;Play&lt;/a&gt;&lt;/td&gt;").appendTo('#libtable');
          }
      }
      $('#loadinggif').hide();
  }
  </code></pre>
  
  <p>As I said before, for the first couple of letters typed, this is very slow and laggy. I am looking for ways to refine this to make it much faster and more smooth.</p>