流星表现:不确定出版是否导致滞后

时间:2015-04-05 17:30:40

标签: meteor

我的Meteor应用程序在开始时缓慢运行大约十秒钟,然后再次变快。我正在努力提高性能,但却找不到真正的原因。

我认为问题在于我发布了以下所有课程信息:

if (Meteor.isServer) {
  Meteor.publish("courses", function() {
    return Courses.find();
  });
}

我尝试使用Kadira来准确监控正在发生的事情。然而,看着结果,我开始认为这可能不是真正的问题。

enter image description here

如果pubsub响应时间只需要292ms,那就不应该感觉有点迟钝,但我想不出为什么应用程序在开始时会如此缓慢并再次变得快速的任何其他原因。专家可以指点我重定向吗?

更新

通过进行以下更改,我可以在一开始就改善延迟的持续时间:

/server/publications.js

中的

if (Meteor.isServer) {
  Meteor.publish("courses", function() {
    // since we only need these two fields for the search bar's autocomplete feature
    return Courses.find({}, {fields: {'catalog':1, 'titleLong':1}});
  });

  Meteor.publish("courseCatalog", function(catalog) {
    // publish specific information only when needed
    return Courses.find({"catalog": catalog});
  });
}

并且在router.js我做了相应的更改,因此我根据特定页面进行了订阅。但是一开始还有一些滞后,我想知道我是否可以进行更多的优化,以及开始时缓慢的真正原因是什么。

UPDATE2:

我按照这个建议进行了如下修改:

启动时

Session.set('coursesReady', false);

并在路由器中:

Router.route('/', function () {
  Meteor.subscribe("courses", function(err) {
    if (!err) {
      console.log("course data is ready")
      Session.set('coursesReady', true);
    }
  });
  ....

并在/lib/helpers.js中返回typeahead库的数据

if (Meteor.isClient) {
  Template.registerHelper("course_data", function() {
    console.log("course_data helper is called");    
    if (Session.get('coursesReady')) {
      var courses = Courses.find().fetch(); 
      return [
        {
          name: 'course-info1',
          valueKey: 'titleLong',
          local: function() {
            return Courses.find().fetch();
          },
          template: 'Course'
        },

但现在的问题是,当调用辅助函数时,数据永远不会准备好。控制台打印:

enter image description here

问:如何确保仅在数据准备好后调用辅助函数,或者在数据准备好后再次调用辅助函数?由于Session是被动的,不应该自动再次调用吗?

1 个答案:

答案 0 :(得分:0)

我现在无法检查这一点,但我相信您的问题可能是course_data帮助程序在订阅中的所有1000多个文档都准备就绪之前多次运行,从而导致typeahead包重新运行一些昂贵的计算。尝试这样的事情:

/client/views/global/helpers.js

Template.registerHelper("course_data", function() {
  if (!Session.get('coursesReady')) return [];      

  return [ //...

/client/subscriptions.js

Meteor.subscribe("courses", function(error) {
  if (!error) Session.set('coursesReady', true);
});

更新

真的,Meteor的新功能this.subscribe()Template.instance().subscriptionsReady()非常适合这种情况。 Session不是真正正确的选择,但它应该仍然是被动地更新(不确定为什么它不适合你)。请尝试对/client/views/navwithsearch.js进行以下更改(主要,但主要是两个模板应共享一个搜索模板):

Template.NavWithSearch.onCreated(function() {
  this.subscribe('courses');
});

Template.NavWithSearch.onRendered(function() {
  this.autorun(function() {
    if (Template.instance().subscriptionsReady()) {
      Meteor.typeahead.inject();
    }
  });
});

我们的想法是将订阅的生命周期与实际使用该订阅的视图联系起来。这应该会延迟预先注入,直到订阅完全准备好。