Loading a Large Collection in a Meteor App

戏子无情 提交于 2019-12-25 03:57:41

问题


In a Meteor app, a large collection containing 1000 records is published to the client. However users loading the {{loginButtons} will experience a 3-5 second lag as it fully renders only after all the large collection loads.

It appears that the div #login-buttons rendered by {{ loginButtons }} is rendered instantly on page load, but the div #login-dropdown-list is what's taking some time to start rendering. #login-dropodown-list template

The site is using Meteor 0.7.0.1 with Iron Router.


Update

Here's the template code for the accounts-ui-bootstrap-3 dropdown menu that take a few seconds to load after the rest of the page renders. It's just the basic template from the Meteor package, nothing special.

<ul class="nav navbar-nav navbar-right">
    {{ loginButtons }} 
</ul>

I used to think the problem is due to that this dropdown menu using the Meteor.users collection, so here's my Fast Render route.

FastRender.onAllRoutes(function(urlPath) {
  this.subscribe(Meteor.users);
  this.subscribe(users);
})

This does not seem to help with the problem. I also found out that Meteor.userId() is already defined when the dropdown menu is still not rendered. The dropdown menu only appears/renders at the point in time pointed to by the red arrow, which is the point where all the collections have loaded.

Furthermore, the div #login-buttons rendered by {{ loginButtons }} is rendered instantly on page load, but the div #login-dropdown-list is what's taking some time to start rendering.

Maybe it's how accounts-ui-bootstrap-3 handles the rendering?


回答1:


You can use iron-router's waiton on specific routes and loadingTemplate properties to show the user a progress indicator while the subscription gets ready. As seen on https://github.com/EventedMind/iron-router#waiting-on-subscriptions-waiton

Router.configure({
  layoutTemplate: 'layout',
  notFoundTemplate: 'notFound',
  loadingTemplate: 'loading'
});

Router.map(function () {
  this.route('postShow', {
    path: '/posts/:_id',

    waitOn: function () {
      return Meteor.subscribe('posts');
    }
  });
});

Also, https://atmosphere.meteor.com/package/fast-render is a third party package which integates into iron-router and sends down the initial data along with the template therefore making the page appear loaded with data instantly.

There is a good tutorial about this at http://meteorhacks.com/integrating-iron-router-based-apps-with-fast-render.html




回答2:


I see two other packages that could help you :

Paginated subscription : https://atmosphere.meteor.com/package/paginated-subscription The idea here would be to set a small limit for the initial load, and when the rest is loaded, change the limit to load the rest

Lazy subscription : https://atmosphere.meteor.com/package/lazy-subscription The idea here is not to subscribe at all to your large collection in the first time ; only init it like that :

Post = new Meteor.Lazy('post', function() { Meteor.subscribe('posts'); });

(it does not subscribe to anything)

And then when ready : Template.some_template.get_posts = function() { return Post().find({}); //Note that Post is now a function. }; => it doe subscribe

The second solution may seem more straight forward, but you can manage it way better with the first one.



来源:https://stackoverflow.com/questions/21886969/loading-a-large-collection-in-a-meteor-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!