我正在开发基于浏览器的媒体播放器,它几乎完全用HTML 5和JavaScript编写。后端是用PHP编写的,但它有一个函数可以在初始加载时填充播放列表。其余的都是JS。有一个搜索栏可以优化播放列表。我希望它能够像大多数媒体播放器那样改进。唯一的问题是它非常慢而且滞后,因为整个节目中有大约1000首歌曲,并且随着时间的推移可能会有更多的歌曲。
原始播放列表加载是对PHP页面的ajax调用,该页面将结果作为JSON返回。每个项目有4个attirbutes:
然后我遍历每个对象并将其添加到名为playlist
的数组中。在循环结束时,会创建playlist
的副本backup
。这样我可以在人们优化搜索时优化playlist
变量,但仍然可以从backup
重新填充它,而无需再提出其他服务器请求。
当用户在搜索框中键入密钥时,会调用方法refine()
。它会刷新playlist
并搜索url
数组中每个对象的每个属性(不包括backup
)以查找字符串中的匹配项。如果任何属性中存在匹配项,它会将信息附加到显示播放列表的表中,并将其添加到对象playlist
以供实际播放器访问。
refine()
方法的代码:
function refine() {
$('#loadinggif').show();
$('#library').html("<table id='libtable'><tr><th>Artist</th><th>Album</th><th>File</th><th> </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();
}
正如我之前所说,对于输入的前几个字母,这是非常缓慢和滞后的。我正在寻找方法来改进它,使其更快更顺畅。
答案 0 :(得分:3)
$('#search')
并不便宜。将它移到循环外面。append()
移到循环之外。只需在字符串中累积标记,然后在循环后追加一次。这应该快得多
function refine() {
$('#loadinggif').show();
$('#library').html("<table id='libtable'><tr><th>Artist</th><th>Album</th><th>File</th><th> </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 :(得分:2)
我建议您稍微改变一下您的播放列表信息。只需将第一个字母拆分播放列表信息,就可以获得相当不错的性能提升。
albums = {
'a': [list of albums starting with a],
'b': ...
}
当然,为文件和艺术家做同样的事情。
答案 2 :(得分:1)
你可以做的一件事就是利用jQuery缓存文档片段的能力(这个例子来自John 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');