加速 jQuery AutoComplete(不可避免的长列表)
Posted
技术标签:
【中文标题】加速 jQuery AutoComplete(不可避免的长列表)【英文标题】:Speeding up jQuery AutoComplete (Unavoidably long lists) 【发布时间】:2012-03-18 13:07:10 【问题描述】:我今天下午早些时候开始了加速 jQuery 自动完成的旅程,并决定开始 memcaching 一切可能是个好主意。如本文所建议:Speeding up autocomplete。
但是,即使在安装和使用 Memcached 之后,我仍然会遇到响应时间缓慢的问题。
就我而言,问题在于我正在处理非常长的列表,就我而言,超过 6700 个个人成员。 (所有植物的所有属或属)
瓶颈似乎是在构建表和填充客户端列表,而不是从 Memcached 中检索信息造成的。
如果其他人遇到过这个特殊问题,我很想听听一个聪明的方法来解决它。我将在下面发布我的代码。
注意:此特定页面不对公众开放,我知道存在一些巨大的安全漏洞。
require_once 'oo/Database.php';
$mysqldb = new Database;
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect to memcache");
$sql = "SELECT DISTINCT `Genus` FROM importlist.plants";
$key = md5('query'.$sql);
$result = $memcache->get($key);
//check if we got something back
if($result == null)
//fetch from database
$result = $mysqldb->rawSelect($sql)->getResult();
//set to memcache, expires after 1 hour
$memcache->set($key,$result,0,3600);
//Result array
$Genera = ($memcache->get($key));
//Add required "quotation marks" for autocomplete
foreach ($Genera as &$Genus)
$Genus = '"'.$Genus[Genus].'"';
$Genera = implode($Genera,',');
//PHP to generate jQuery
echo <<< EOT
<script>
$(function()
var availableTags = [$Genera];
$( "#tags" ).autocomplete(
source: availableTags
);
);
</script>
EOT;
?>
<input id="tags" />
【问题讨论】:
不知道这会加快速度,但您应该可以设置$Genera = $result
而不是第二次调用内存缓存。或者更好的是,只需在 foreach()
中使用 $result
而不是 $Genera
可以在页面加载后或用户尝试使用自动完成功能之前使用 ajax 请求来填充数据吗?
看起来您正在模拟创建数组的 json 表示法。可能json_encode
会给你比 foreach 更快的速度。但是,您应该首先找出该代码块的哪一部分消耗了这么多时间。首先通过运行一些指标来定位瓶颈。
XDebug 或许可以帮助您找到瓶颈所在。
【参考方案1】:
由于在用户输入至少 1 个字符之前您无法查找任何内容,因此您可以创建 26 个不同的列表。每个自动完成列表仅包含以该字母开头的项目。您的列表将明显更小,加载速度更快。
要使其更快,请创建更多列表。您可能只需要显示前 30-40 个项目。如果该项目不在缩短的列表中,用户很可能会键入另一个字母。然后,您可以将列表划分为 26*26 个唯一列表。每个列表仅包含以前 2 个字母开头的项目。
您可以根据需要将项目分成多个列表。我们在我管理的网站上执行此操作,我们的预输入中有超过 500,000 个可用项目。
【讨论】:
【参考方案2】:$(document).ready(function()
// once page loads, make AJAX request to get your autocomplete list and apply to html
$.ajax( url: '/path-to-get-tags-as-json.php',
type: "GET",
contentType: "application/json",
success: function(tags)
$( "#tags" ).autocomplete(
source: tags
);
);
);
将您的 PHP 文件的 URL 放置在上面的 AJAX 占位符 url 参数中生成自动完成列表。在您的 PHP 代码中,修改列表生成,使其返回一个 JSON 数组,如下所示:
[ "first" , "second" , "anotherEntry" , "in" , "the" , "array" ]
这肯定不会加快进程服务器端,但它会保护您的用户在应用自动完成时不会出现一些延迟列表。这在很大程度上假设用户不会立即执行需要自动完成的操作,您仍然可以加载页面并允许用户执行其他操作。自动完成列表的加载在大多数情况下应该是无声且无缝的。
这对于少于几秒到几秒的加载时间非常有用,但如果您花费的时间超过此时间,那么您的用户可能仍会遇到可用性问题。
如果仍然存在服务器端延迟,请考虑使用一些时序语句来尝试确定瓶颈在哪里。
【讨论】:
如果你使用这个,你可以用 json_encode 替换你的 foreach 循环。 正是我的想法。做出改变并不难,它会让它看起来更像 Web 2.0 并且可能会更快一点。我还应该补充一点,Afonso 可能需要在返回 JSON 数组之前将 PHP 中的内容类型设置为“application/json”,以便浏览器将其识别为 JSON。 谢谢jmort,我要深入研究一下代码,非常感谢您的建议! 看起来您正在从 memcached 中获取一个数组。 json_encode 应该自动为您将数组编码为 JSON 字符串。因此,您无需将其括在引号中或对其执行任何操作。在 jQuery 回调函数中检索后,您将能够循环通过该数组,但在 javascript 中。查看json_encode 页面以获取示例和用法。你真的很亲密。 这正是我所需要的。非常感谢。以上是关于加速 jQuery AutoComplete(不可避免的长列表)的主要内容,如果未能解决你的问题,请参考以下文章