我对Meteor很新。我的应用程序具有相当小的数据集,< 1000条记录,我构建了一个相当天真的过滤器即用型实现。
现在,性能非常糟糕 - 每个按键都会导致浏览器在相对较快的计算机上遵守冻结一两秒。
它目前已启用autopublish
并且正在客户端执行所有操作,我知道这是问题的一个重要部分,我只是不确定如何改进它。
这是相关的代码段:
Template.results.codes = function () {
var query = Session.get("query")
// todo: figure out if there's a better way to do this
var search = (query && query.length > 3) ? {$where: function() {
return this.code.indexOf(query) != -1;
}} : {}
return Codes.find(search);
};
您可以在https://github.com/nfriedly/Meteor-ODB-II查看完整来源,然后在http://odb-ii.meteor.com/
进行试用我有具体问题:
答案 0 :(得分:5)
欢迎来到流星!如果这是一个生产应用程序,我的第一个评论是你不应该使用自动发布 - 尤其不是1k记录。正确的方法是使用更复杂的分页框架。除此之外,我们可以通过一些调整使您当前的UI更快:
where
快得多。这本身就是一个巨大的胜利。isMatch
调用codes
这是一个非常大的性能影响因为它重新运行已经很昂贵的查询两次。相反,我们可以用会话变量替换此调用。> 1
,这似乎仍然很快。但你应该调整味道。以下是我的更改:
Template.results.codes = function () {
var query = Session.get('query');
var cursor = query && query.length > 1 ? Codes.find({code: new RegExp(query)}) : Codes.find({}, {limit: 100});
Session.set('isMatch', cursor.count() > 0);
return cursor;
};
Template.results.isMatch = function() {
return Session.get('isMatch');
};
以下是运行meteor remove autopublish
后如何使其工作的快速示例。
向您的客户添加订阅:
Tracker.autorun(function() {
Meteor.subscribe('codes', Session.get('query'));
});
向您的服务器添加发布:
Meteor.publish('codes', function(query) {
if (query && query.length > 1) {
return Codes.find({code: new RegExp(query)});
} else {
return Codes.find({}, {limit: 100});
}
});
然后,您可以从limit
功能中删除Template.results.codes
。在发布中,我认为您需要以聪明的方式调整limits
和query.length
的使用,但这应该让您开始。我希望有所帮助!
答案 1 :(得分:1)
您可以做的最重要的事情之一是优化您为过滤式搜索而发布的集合。使用自动发布不是一个选项。
Here是使用超过80,000个单词的字典的示例实现。 Here's the source.
对于'加载'效果,我会使用Iron-Router的waitOn
方法,链接也会在评论中
答案 2 :(得分:0)
我同意“正则表达式”运算符是一个很好的方法。只要确保你适当地处理“特殊字符”。例如,您希望允许您的用户在未经验证的情况下将“*”(星号)等通配符传递给mongo,还是应该将其视为文字?
答案 3 :(得分:0)
我为此目的创建了一个autocomplete package,它支持过滤客户端和服务器端集合。它以Meteor的集合和反应性为基础,而不是像typeahead这样的基于数组的方法。
它使用了此线程中的大多数建议,即使对于1000个记录的集合,它在客户端上也相当快,并且可以使用服务器上的索引对于大型集合更快。