Reactive vars are heavily slowing down my app -- what am I doing wrong?

I have an interface where the server will update a collection and I want to watch it and update the ui as it’s changing. Here’s what I do:

Template['Dashboard.content'].onCreated(function () {
  this.cycleMessage = new ReactiveVar('Executing');
  this.isExecuting = new ReactiveVar(false);
  this.current = new ReactiveVar({});

  let updateCurrent = function (doc) {
    let card = OrderCards.findOne(_.first(doc.jobs)._id);
    this.current.set({
      card: card,
      order: Orders.findOne(card.orderId)
    });
  }

  this.autorun(() => {
    Scheduler.cycles.find({
      _id: FlowRouter.getQueryParam('cycle')
    }).observe({
      added: updateCurrent,
      changed: updateCurrent
    });

    Connections.find({
      name: 'messages'
    }).observe({
      changed: (doc) => {
        this.cycleMessage.set(_.last(doc.messages).message);
      }
    });
  });
});

It’s going very, very slow and on a fast computer. What’s going wrong here?

Well, I never seen cursor.observer in autorun.
I would not be surprised if it was spawning new observer every re-run.

Why you even need it in autorun?

I don’t think I do, but removing the autorun still makes it run slowly.

I wasn’t sure if the cursor persisted after the creation hook passed

Yes they do persist.

Maybe if you better define slow, how many times it need to re-run the query per second etc.
And where/how is that “current” ReactiveVar being used later, if it could not be some issue with re-rendering there.

Nope, as per the doc:

If observe is called from a Tracker.autorun computation, it is automatically stopped when the computation is rerun or stopped.

However, there is a problem with the autorun: it keeps a reactive dependency on every initial call to added->updateCurrent->OrderCards.findOne(). See here:

To solve this, change updateCurrent like this:

let updateCurrent = function (doc) { 
  Tracker.nonreactive(function() {
    // Your code here
  });
}

In fact, until the issue is fixed, you might want to always use Tracker.nonreactive in observe hooks.

2 Likes