First let me tell you about the app I’m trying to code, its a database of animes tv series/movies and mangas, and the user can filter the genres and themes he wants to search for.
Now for my problem, I have a huge number of results to show to the user and the application is slowing down while im rendering it all and I realize my approach with publishing and subscribing might be the root of the problem.
Heres my publish:
Meteor.publish("filteredWorks", function (filters) {
if (filters !== null) {
if (filters.genres !== undefined && filters.genres !== "") {
filters.genres = filters.genres.split(",");
}
if (filters.themes !== undefined && filters.themes !== "") {
filters.themes = filters.themes.split(",");
}
var queryObject = Meteor.call("createWorkQueryObject", filters);
if (_.isEmpty(queryObject)) {
return [];
}
return Works.find(queryObject, {sort: {name: 1}});
}
});
And heres my subscribe:
Tracker.autorun(function () {
var filters = Session.get("filters");
Meteor.subscribe("filteredWorks", filters);
});
What do you guys think of this approach? What bothers me right now is that depending on the filter, thousands of titles need to be rendered on screen and the application takes way too long and slows down the browser.
You can see the whole code here, it is a WIP though.
Just a question, are you going to make it of MAL scope or is it just for testing / learning / personal use?
I’m asking because in upcoming time Anilist switches to open source, they just need to finish refactoring the code. Although they’re on Laravel + Angular stack.
I’m already dealing with 25 items chunks in my filtered query, but I’m observing that the time between subscription ready and the end of Tracker.afterFlush increases with the # of records I fetch.
Even with just 325 records I got almost 1 sec between the 2 and my sub template is damn simple. I’ve something like:
In Messages Template onCreated I have some thing like this:
Template.messages.onCreated(function(){
var that = this;
this.autorun(function(){
that.subscribe('messages', Session.get('current-channel')._id, Session.get('messages-limit'));
});
this.autorun(function() {
if (that.subscriptionsReady()) {
Tracker.afterFlush(function(){
// do some minor stuff that takes 1-5% of the exec time
});
}
});
});
Now I supposed that stopping Blaze rendering before subscribe and starting it again after subscriptionsReady could provide some benefits, but I don’t know how to do it.
Blaze rendering can be suspended with an #if, just like you do in your template code. This way Blaze doesn’t progressively update the DOM while receiving the data. Indeed, it is often best to render the DOM once and for all after the initial subscribed data set is fully loaded (this issue might be fixed in the near future, see here).
Your case is different: since you already wait for the subscription to be ready before rendering anything, the problem comes from somewhere else. You can start by checking those helpers to see if they are not too cpu-intensive: allMessages, getMessageId, messageBody.