流星一次或"static"发布,无需收集跟踪



假设需要将相同的 10,000 个文档集合发送给 Meteor 应用程序的每个客户端。

在高级别上,我知道服务器为每个客户端订阅做一些簿记 - 即,它跟踪订阅的状态,以便它可以为客户端发送适当的更改。但是,如果每个客户端都有相同的大型数据集,其中每个文档都有许多字段,则效率非常低。

似乎曾经有一种方法可以发送"静态"发布,其中初始查询已发布并且再也没有更改。这似乎是一种更有效的方法。

在当前版本的 Meteor (0.6.5.1) 中是否有正确的方法可以做到这一点?

编辑:作为澄清,这个问题与客户端反应无关。这是关于减少客户端集合的服务器端跟踪开销。

一个

相关的问题:有没有办法告诉流星一个集合是静态的(永远不会改变)?

更新:事实证明,在 Meteor 0.7 或更早版本中执行此操作会导致一些严重的性能问题。请参阅 https://stackoverflow.com/a/21835534/586086 了解我们如何解决此问题。

http://docs.meteor.com/#find:

Statics.find({}, {reactive: false} )

编辑以反映评论:

您是否有一些信息表明反应式:错误参数只是客户端? 你可能是对的,这是一个合理的,也许可能是可能的解释。 我没有时间检查,但我认为这也可能是服务器端指令,说不要轮询 mongo 结果集。 愿意学习...

你说

However, this is horribly inefficient if each client has the same large data set where each document has many fields.

现在我们可能正在讨论服务器代码的效率,以及它对 mongo 源代码的轮询,以获取服务器外部发生的更新。 请再问一个问题,这个问题远远超出了我的回答能力! 我怀疑每个连接的客户端都会发生一次,更有可能是应用程序服务器信息和mongo服务器之间的同步。

您发出的客户端请求(包括排序)都应标记为非反应性。 这与您是否可以通过排序指令发出它们,或者它们是否可以通过其他反应性重新触发是分开的,但不需要包括到服务器的访问。 每个文档到达客户端后,就会被缓存。 你仍然可以做任何小蒙戈做的事情,没有能力损失。 没有客户端询问服务器是否有更新,您无需将其关闭。 服务器仅在需要时推送。

我认为使用手动发布(this.added)仍然可以摆脱服务器观察数据更改所产生的开销。 观察器要么需要手动添加,要么通过返回 Collection.curser(通过返回 Collection.curser) 来创建。

如果数据集很大,您可能还担心合并框的开销,该合并框包含每个客户端的数据副本。 要摆脱这种情况,您可以在本地复制集合并停止订阅。

var staticData = new Meteor.Collection( "staticData" );
if (Meteor.isServer ){
  var dataToPublish = staticData.find().fetch();  // query mongo when server starts
  Meteor.publish( "publishOnce" , function () {
    var self = this;
    dataToPublish.forEach(function (doc) {
      self.added("staticData", doc._id, doc);  //sends data to client and will not continue to observe collection
    });
  });
}
if ( Meteor.isClient ){
  var subHandle = Meteor.subscribe( "publishOnce" );  // fills client 'staticData' collection but also leave merge box copy of data on server
  var staticDataLocal = new Meteor.Collection( null );  // to store data after subscription stops
  Deps.autorun( function(){
    if ( subHandle.ready() ){
      staticData.find( {} ).forEach( function ( doc ){ 
        staticDataLocal.insert( doc );  // move all data to local copy
      });
      subHandle.stop();  // removes 'publishOnce' data from merge box on server but leaves 'staticData' collection empty on client
    }
  });
}

更新:我在代码中添加了注释,以使我的方法更加清晰。 订阅句柄上stop()的流星文档说"这通常会导致服务器指示客户端从客户端的缓存中删除订阅的数据",所以也许有一种方法可以停止订阅(从合并框中删除)将数据留在客户端上。 这将是理想的,并避免客户端上的复制开销。

无论如何,使用 setflush 的原始方法也会将数据留在合并框中,所以也许没关系。

正如您在googlegroups中已经指出的那样,您应该使用Meteor方法将静态数据发送到客户端。
并且有一个整洁的软件包,用于使用方法而不会产生异步头痛。

此外,您可以将数据脚本化为 js 文件,作为数组或对象,将其最小化,然后作为不同的资源链接到它。 看http://developer.yahoo.com/performance/rules.html 添加过期或缓存控制标头。 你可能不希望流星为你捆绑它。

这将是最少的流量,并且可以使您的网站的后续加载速度更快。

作为对 Meteor 调用的响应,返回一个文档数组(使用 fetch()) 没有反应性或日志记录。 在客户端上,在执行查询时创建 dep,或从会话中检索密钥,它在客户端上是反应性的。

Mini mongo只是使用解释你和你的数据之间的dsl的语法进行js数组/对象操作。

新的快速呈现包使一次性发布到客户端集合成为可能。

var staticData = new Meteor.Collection ('staticData');
if ( Meteor.isServer ){
  FastRender.onAllRoutes( function(){
    this.find( staticData, {} );
  });
}

相关内容

最新更新