Thinking that this was a problem with subscriptions, we implemented SubsManager for subscription caching. From profiling with Kadira, we now know that subscriptions are cached and that this is not a cause of slow page display times; going back and forth between the “home” and “degree planner” pages shows a consistent multi-second wait time, but no subscription-related events:
So we’re trying to figure out what to try next (other than move to React), and one idea is to cache Templates as well as subscriptions. Arunoda showed an example of how this could help in a three minute YouTube video a while back:
Unfortunately, I can’t find further details, so I’m asking the community for guidance. I am willing to pay the 4 second overhead to display the page the first time, as long as it displays quickly from then on. Are there blog posts, packages, or example code out there that we can use to implement Template caching?
This has been on my backlog for a while now and seeing this video reminded me of that. Let me know if you make progress, get stuck, etc. as I’ll be looking at this (hopefully) pretty soon.
The slowness in the part where stuff is actually rendering is from your templates looking stuff up in Minimongo (findOne, fetch, observe, etc.). So if you can decrease the number of calls you’re making or make it less reactive (less expensive to do a minimongo call in that case) or do some caching, then you’ll be good. It’s not core Blaze rendering being slow. If you fix this you could shave off 2 seconds.
About 500ms is coming from just loading your code, but it looks like it is literally just doing module stuff so not much you can do there.
You’ve got another 500ms loading publications.
I’d focus on fixing the the expensive Minimongo stuff and then look at the data loading stuff. Do you know how to read the flamechart from the CPU profile? It will show you exactly which functions are doing expensive Minimongo lookups.
Edit: These numbers are based off the CPU profile you posted. In the timeline view you posted things are a bit different, fixing the minimongo stuff would fix closer to 3.5 seconds.
Thanks for the suggestions. We have implemented template caching with an ES6 compatible version of Arunoda’s blazer. js. Here it is:
It does indeed speed things up a lot, but now our Semantic UI components do not work correctly when we come back to the page because the onRendered code is not called for cached templates. For example:
We’re not sure how to re-call the onRendered function from within Blazer.js after retrieving a cached template, or even if this makes sense (i.e. is ‘this’ going to be bound correctly?)
I really don’t think Arunoda’s template caching code is the right approach here; it feels pretty brittle as-is. Your underlying performance problems look super solvable, I’d focus on those.
Well, thanks to all of your great suggestions, we discovered that: (a) the lion’s share of our performance problem was due to a single control: the “Add” button in each semester, and (b) we can move that button to our “Inspector” on the same page which actually increases the usability of the system. Simply moving the Add button means we don’t need to cache templates and our page loads in about a second. Win-win!
I’ve learned a LOT about Blaze and performance analysis in Meteor this week. Really fun! Thanks again.
It turns out that each semester’s “Add” button had to do a non-trivial amount of computation to figure out how to populate its menu (we wanted to restrict the set of courses and opportunities to only those that were “valid” for that particular semester, and there were a bunch of properties that needed to be checked for validity). Multiply that computation for 10 or so semesters and suddenly you’re talking multiple seconds of delay before displaying the page. And then each time someone changed the set of courses and opportunities for one semester, the menus for all subsequent semesters would need to be recomputed because the set of valid menu items might now be different, so you can’t really pre-compute and cache the items.
By moving the button to the Inspector, we can now compute only a single Add button’s menu contents, and only when the user actually might want to push it. Problem solved!