More efficient to subscribe on a global level rather than in components?

I’m building an app where the user could be doing a fair amount of navigating from page to page. Since I’m subscribing at a component level (for the sake of this example, collections called “Things” and “People”) and some pages do not reference Things or People at all, I’m wondering if it makes more sense to just subscribe to these at a global/layout level. That way they’re always there, rather than unsubscribing and re-subscribing as the user navigates.

Or is there no performance concern to worry about?

2 Likes

+1, I’d really like to know the performance difference between subscribing to all data at route level (say with publish-composite/publish-with-relations vs self-subscribing reusable templates (/components).

do we end up creating the same observers with both strategies?

Hopefully someone can shed some light

It does vary on many factors and specifics of your app and data. I tend to settle down in a mixture of both approaches in the same application, plus app cacheing subscriptions where appropriate:

Low-update type subscriptions that are required throughout many parts/pages of an application (e.g., reference tables) are ideal for global/higher-level templates so they are subscribed once and remain resident on the client for the whole session. These also tend to be the type of subscriptions that are reused across many clients (same query criteria) which tends to be good from the server perspective.

Other subscriptions make more sense at the lower-level templates where they are used. Thing like data needed for CRUD style processing where you need all the data for a specific document, in selected screens that are not often used for the same document in the same session, so you can display/update details.

Somewhere in between, I found that some package like ccorcos:subs-cache can be very useful, saving the unsubs/subs for same document that sometimes happens when the user tends to go in/out/in of screens that need the same subscription in a short time frame (e.g., change some document in a screen/page, then go out to another route to check the effect, then comeback again to update to try something else…).

To check the effect on the server of different approaches, percolate:server-info is a package that I found quite useful.

Are you using React? Have you looked at Redux? I’m going to be putting my subscription data straight into my single global store to be accessible by all components. I guess you could call that global. It’s the easiest/fastest way imo.

You should use subsmanager or the ccorcos version of the package.

Yes. It makes a difference. This is much more efficient than resubscribing over and over.

1 Like

Subscribing at a global level for certain collections makes sense to me, especially if they’re used on all pages (or most). Why do I need a package like subsmanager though? I can simply execute my Meteor.subscribe calls in the layout which wraps all pages, and it’s done.

Yes and yes :slight_smile: But Redux can’t detect changes in MongoDB. I mean, I suppose I could use observeChanges or something along those lines to fire off a Redux state change, but why not just use what Meteor provides?

If you expect to have consistent fetching needs for data between routes, I would put this in the global subscriptions space.

I for one, am against meteor data in redux but that’s just me.

Totally agree. Though it can be useful to use Redux as a place to temporarily store data while it’s been edited by the user, before saving it in its entirety into MongoDB.

Yes, to me “Meteor Data” is data bound to you by Meteor constructs: minimongo, tracker etc. As opposed to meteor methods, which can just return objects is a perfect place to dump into a Redux store.

If your meteor data is triggered by tracker in shouldComponentUpdate or something similar, then you can’t do pure components. Your tests will be filled with mocks for tracker, subscription callbacks etc, not sure how that would be done.

Alternatively, if you use subscriptions and tracker to update your store, then the relationship between store and components is kept clean. Most components are pure, container components that has the state->prop or dispatch->prop relationships are easily testable (they are also pure functions).

As I was saying in another thread, it feels like meteor’s tracker, minimongo, session, reactives and redux do not work well together. As in, you have one or the other. But working with Redux over the last 6 months, I’ve come to realise how powerful the architecture is because it’s simple to test and it’s simple to develop components with.

1 Like

I had a very similar question.

In the end I implemented subs manager, however I still do subscribe to most of the data when I create the Layout component which is the top level and always used in the app.

I decided to move a couple subscriptions into the layout component, and I definitely saw a performance boost while navigating between pages!

I created this package to save more time when structuring pages and optimizing performance for calling Meteor.subscribe, you don’t worry about best solutions for it.