0

I just wrote a small program in meteor and using MongoHQ running under Heroku. This simple app will create a live count of how many people submit the email. You can find the example here: DearJJAbrams Here is the collection:

Counts = new Meteor.Collection("supporters");

On client side, I run:

Template.CountWrapper.SupporterCount = function () {
    return  Counts.find().count();
};

Template.BodySupporter.events({
    'click .support-click' : function () {
      if ($("#supportInputName").val() != "") {
        Supporters.insert({name: $("#supportInputName").val()});
        $(".signup-form").fadeOut(600, function() {
          $(".thank-you-message").fadeIn(600);
        });
      }
      return false;
    }
})

The problem is that when the number of users submit their email include, the database seems to do the count query very slow. Is there any better way to handle this? Thank you.

Khoa Pham
  • 285
  • 3
  • 10

1 Answers1

1

A look over the raw DDP socket shows you're sending down the entire collection to the client, so in effect everyone downloads the entire 'supporters' collection.

This looks like the bit inefficient. This is because you send down the whole collection (~7000 records - which each looks to be ~100 bytes on the DDP wire), in total nearly 1 mb of data to be downloaded.

So these have to be downloaded first, then the count can be displayed. Why not store the count in a separate collection and only send that down? It should be much faster that way. Unless you're giving the entire list of names on a table or something somewhere it might be better to do this.

The other thing is on your hosting provider you're not letting websockets work so meteor falls back to long-polling (XHR) which is a bit slower to initially connect since there is all this extra overhead. You might want to look at something you have in between, typically a proxy or firewall that isn't configured to let through websocket requests.

Tarang
  • 75,157
  • 39
  • 215
  • 276
  • I totally agree with you that implementing this way is very inefficient. I have try to create another collection just storing the counts number, but I cannot use update() function of Meteor on the client site [meteor update](http://docs.meteor.com/#update). I just got the error Untrusted code... Do you have any suggestion for implementing this on the server side. Can I use any method like pulish() or subscribe to get this update on the server? – Khoa Pham Sep 30 '13 at 01:45
  • The untrusted code error means you need to add allow/deny rules and secondly use the `_id` field to update (if you run it on the client). I would suggest that you use the `insert` and `remove` `.allow`/`.deny` rules of your supporters collection, so that when you add a new record it automatically increments the counter – Tarang Sep 30 '13 at 07:40
  • Akshak, I have implemented another collection for counter only. However, the entire collection of Supporter is still downloading to the client side. Now I just want to move the insert() when someone input their email to the input field. Is there anyway I can call insert() to the Collection without downloading the whole collection. – Khoa Pham Oct 01 '13 at 05:10
  • Yes! You can still do that. You have to make sure you don't publish the collection, it can still exist though! Just it wont download any data. Just in case you havn't make sure you `meteor remove autopublish` too – Tarang Oct 01 '13 at 06:13
  • Yes. Remove autopublish really help to reduce the loading time of the unnecessary collection. It's now working pretty good, you can see it at: (http://www.dearjjabrams.com/) – Khoa Pham Oct 02 '13 at 04:07