I’m not quite sure how to even describe this, but I’ve built a lazy load mechanism that makes a request when the user is approaching the bottom of the page. It goes like this:
React component detects scroll reaching end of page.
Call made to this.props.requestMore().
This goes into my Paginator class, which is keeping track of our current subscription limit, if we already have a request being processed (to avoid hundreds of calls made from scroll events). See requestMore code below.
The new limit is set (ReactiveVar).
In the TrackManagerContainer, I have a subscribe call that uses limit.get().
Publish function returns a new set of data.
All is right in the world.
And this works fine on the first page load. But if I navigate away and then come back to that page, randomly something weird happens in between steps 4 and 5 above. limit is set to a new value, but it takes about 2-3 seconds before I see my console.info statement tell me that it’s about to call Meteor.subscribe. I can’t figure out why on earth there would be such a massive delay between those two things.
I know it’s probably nearly impossible to tell without an accessible repro and code base. But if this behavior sounds familiar to anyone, please let me know!
I managed to capture a screencap. The first lazy load works great. Watch the second one, and notice how in the client, it says “Paginator: increasing limit to 30” and it gets stuck before the “TrackManagerContainer: subscribe to tracks, limit 30” message (and the “publish tracks” message on the server side).
It’s safe to assume then this could stop the current subscription and then re-subscribe. So what you might be seeing here is the time taken to (re)generate the cursor on the server. That time is unlikely to be your Meteor code, but (especially if your collection has many documents) could well be in Mongo. Long delays on queries with sorts (and limits) says indexing to me. I would suggest a compound index on snippet and createdAt to optimise that find. You could do this through the Mongo shell:
Ah well, it was worth a shot. Indexing on artistId and createdAt didn’t help either. The time isn’t being spent in the publication anyway, it seems. The publication function is entered and exited in a fraction of a second. I feel like something is weird with the Tracker, because handle.ready() remains true (otherwise there would be a spinner that shows up).
Wow, so I removed publications totally from the picture. In other words, I’m subscribing to all data globally. I modified my paginator so all it does is just increase the Reactive Var and then it’s passed to the client-side find call:
This is still an issue after an upgrade to 1.4.2. See how much idle time passes between setting the limitReactiveVar and the time it takes for the Meteor container to redraw. I’ll try to put together a repro.