2010-03-19 109 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