2010-03-19 67 views
2

我正在研究基于浏览器的媒体播放器,它几乎完全是用HTML 5和JavaScript编写的。后端是用PHP编写的,但它有一个功能是在初始加载时填充播放列表。其余全部是JS。有一个搜索栏可以改善播放列表。我希望它能够像人们打字一样进行细化,就像大多数媒体播放器一样。唯一的问题在于它非常缓慢且迟缓,因为整个节目中大约有1000首歌曲,而且随着时间的推移,可能会有更多的歌曲。优化JS Array搜索

原始播放列表加载是对PHP页面的ajax调用,它将结果作为JSON返回。每个项目都有4个attirbutes:

  1. 艺术家
  2. 专辑
  3. 文件
  4. 网址

我然后依次通过每个对象,并将其添加到一个数组叫playlist。在循环结束时创建playlist的副本,backup。这样,我可以在人们优化搜索时优化playlist变量,但仍然从backup重新填充它,而不发出其他服务器请求。

方法refine()在用户在搜索框中键入一个键时调用。它会刷新playlist并搜索backup数组中每个对象的每个属性(不包括url),以查找字符串中的匹配项。如果任何属性匹配,它会将信息附加到显示播放列表的表格中,并将其添加到对象playlist以供实际播放器访问。

代码为refine()方法:

function refine() { 
    $('#loadinggif').show(); 
    $('#library').html("<table id='libtable'><tr><th>Artist</th><th>Album</th><th>File</th><th>&nbsp;</th></tr></table>"); 
    playlist = []; 
    for (var j = 0; j < 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; 
      $("<tr></tr>").html("<td>" + num + "</td><td>" + sartist + "</td><td>" + salbum + "</td><td>" + sfile + "</td><td><a href='#' onclick='setplay(" + num +");'>Play</a></td>").appendTo('#libtable'); 
     } 
    } 
    $('#loadinggif').hide(); 
} 

正如我之前所说的,对于第一对夫妇的键入的字母,这是非常缓慢和laggy。我正在寻找方法来改善这一点,使其更快更顺畅。

回答

3
  1. $('#search')并不便宜。将它移到循环之外。
  2. 移动append()以外的循环。只需在一个字符串中累加标记并在循环后追加一次即可。

这应该是更快

function refine() { 
    $('#loadinggif').show(); 
    $('#library').html("<table id='libtable'><tr><th>Artist</th><th>Album</th><th>File</th><th>&nbsp;</th></tr></table>"); 
    playlist = []; 
    var srchText = $('#search').val().toLowerCase(); 
    var markup = ["<tbody>"]; 
    for (var j = 0; j < backup.length; j++) { 
     var sfile = backup[j].file.toLowerCase(); 
     var salbum = backup[j].album.toLowerCase(); 
     var sartist = backup[j].artist.toLowerCase(); 

     if (sfile.search(srchText) !== -1 || salbum.search(srchText) !== -1 || sartist.search(srchText) !== -1) { 
      playlist.push(backup[j]); 
      num = playlist.length-1; 
      markup.push("<tr><td>" + num + "</td><td>" + sartist + "</td><td>" + salbum + "</td><td>" + sfile + "</td><td><a href='#' onclick='setplay(" + num +");'>Play</a></td></tr>"); 
     } 
    } 
    markup.push("</tbody>"); 
    $("#libtable").append(markup.join('')); 
    $('#loadinggif').hide(); 
} 
1

有一两件事你可以做的是采取的jQuery的缓存文件片段的能力优势(的例子是从通话约翰Resig的了,但你可以把它应用到你的代码):

// SLOW AS IT IS NOT CACHED. BECAUSE OF FOO 
$("ul").append("<li><a>" + foo + "</a></li>"); 

// FAST. DOCUMENT FRAGMENT IS CACHED 
$("<li><a></a></li>") 
    .find("a").text(foo).end() 
    .appendTo("ul"); 

这将是适用于你上面的一行:

$("<tr></tr>").html("<td>" + num + "</td><td>" + sartist + "</td><td>" + salbum + "</td><td>" + sfile + "</td><td><a href='#' onclick='setplay(" + num +");'>Play</a></td>").appendTo('#libtable'); 
2

我建议有点不同构建您的播放列表信息。通过首字母分割播放列表信息,您可能会获得相当不错的性能增益。

albums = { 
    'a': [list of albums starting with a], 
    'b': ... 
} 

当然,对于文件和艺术家也是这样做的。

+1

+1预先烹饪数据的格式,使后面的操作更有效。 – 2010-03-19 04:34:40