【问题标题】:Meteor - Publications causing long loading timeMeteor - 导致加载时间过长的出版物
【发布时间】:2017-09-08 23:49:35
【问题描述】:

我正在尝试制作一个相当大的流星应用程序,但我注意到过去几天它变慢了,我在流星论坛上看到出版物可能会导致加载时间变慢。在我对应用程序本身进行更改(代码更改)时刷新页面后,一次更改通常需要 1-2 分钟。我的出版物有什么问题吗?虽然,当页面加载时,我重新加载它加载速度非常快。

if(Meteor.isServer){
  Meteor.publish('notes', function () {
    return Notes.find()
  });
  Meteor.publish('users', function () {
    return Meteor.users.find()
  });
  Meteor.publish("user", function(){
    return Meteor.user()
  })
  Meteor.publish('notes-newest', function () {
    return Notes.find({}, {sort: {createdAt: -1}, limit: 10});
  });
}

文档示例:

let noteInfo = { title, subject, description, imageURL, userId, userEmail, createdAt }
let title = this.refs.title.value;
let subject = this.refs.subject.value;
let description = this.refs.description.value;
let allUrls = [this.refs.imageURL.value].concat(this.state.urls);
let imageURL = allUrls.filter(function(entry) { return entry.trim() != ''; });
let userId = Meteor.userId();
let userEmail = Meteor.user().emails[0].address;
let createdAt = Date.parse(new Date());

【问题讨论】:

    标签: meteor


    【解决方案1】:

    这是一个非常广泛的性能调优问题。您还没有告诉我们您的收藏中有多少文档或这些文档有多大。一些可能的问题:

    过度发布要么是因为发布了太多文档,要么是因为您的文档太大。例如,当你这样做时:

    Meteor.publish('notes', function () {
      return Notes.find()
    });
    

    如果有 100,000 个 Notes 文档,每个文档 100 字节,则需要通过网络传输到客户端的 10 MB。如果有 1,000 个注释文档,每个 10KB,情况也是如此。

    解决方案:使用limit 限制文档数量和/或减少使用fields 传输的字段数量:

    Meteor.publish('notes', function () {
      return Notes.find({},{ limit: 100, fields: { key1: 1, key2: 1 }});
    });
    

    您的收藏缺少一个或多个索引。当你这样做时:

    Meteor.publish('notes-newest', function () {
      return Notes.find({}, {sort: {createdAt: -1}, limit: 10});
    });
    

    如果有 1M 个笔记文档,但 createdAt 键上没有索引,那么这将非常慢。

    解决方案:createdAt 键上添加index 将使此类发布更快。

    您有一个无效的出版物

    Meteor.publish("user", function(){
      return Meteor.user();
    })
    

    无效,因为Meteor.user() 不是游标,并且发布必须返回游标或游标数组。它也是冗余的,因为Meteor.user() 在客户端上自动可用,尽管它不包括所有密钥。

    解决方案:完全删除这个不必要的出版物。如果您想为当前用户发布一些在客户端上不可用的密钥,您可以执行以下操作:

    Meteor.publish("user", function(){
      return Meteor.users.find(this.userId,{fields: {services: 1, emails: 1, profile: 1}})
    });
    

    【讨论】:

    • 抱歉,我的情况过于笼统。我的应用程序文件夹总大小约为 180mb,笔记集中只有大约 20 个文档。我现在只是想开发一个工作网站,所以当我有成品时,我会添加对出版物的限制。我还在我的一个集合中添加了一个文档示例(不确定它们在应用程序中的存储位置,因此无法检查大小)。
    【解决方案2】:

    在我进行更改时刷新页面后,一次更改通常需要 1-2 分钟。我的出版物有什么问题吗?虽然,当页面加载时,我重新加载它加载速度非常快。

    这是什么意思?您的意思是当您更改网站的代码时,您的更改需要 1-2 分钟才能出现在新加载的页面中?这是意料之中的:Meteor 需要时间来重建您的应用程序。观看终端以了解进度。

    使用大量包和外部代码会减慢构建速度。编译速度与最终用户的体验无关。

    【讨论】:

    • 是的,它应该很慢,但偶尔会在 5-10 秒左右加载得很快。但大部分时间需要 1-2 分钟。
    • "加载速度非常快,大约 5-10 秒。" — 当您只修改 CSS 时会发生这种情况。如果在服务器端修改代码,则需要 1-2 分钟。如果修改仅在客户端加载的代码,可能需要 10 秒到 2 分钟。此行为是设计使然。您的问题没有其他解决方案。
    • 我只想说,您的问题并没有以其他评论者清楚的方式真正说明您遇到的问题。您的问题是应用程序中的构建时间缓慢,它与出版物无关。除了使用更少的代码,没有其他解决方案。
    【解决方案3】:

    我对我的流星项目做的几件事是我发送特定字段“profile.name”等。我还使用了 collection.createIndex({}) 它创建一个索引并在其中创建一个索引,你可以把你的排序其中是在服务器启动时创建的,并且适用于您的 collection.find.sort。我认为限制你的笔记是非常必要的,因为你有一个限制,而不是另一个。

    【讨论】:

      【解决方案4】:

      这也发生在我身上。当时我检查了 kadira(以前仍然是开源的,但现在不是)。源代码在kadira on github,但服务不见了kadira.io

      问题在于发布和订阅。当客户请求订阅时,他打开了某种“连接”——我这么说,它适用于调用同一出版物的其他人。想象一下形成了多少连接。 许多人访问的相同数据必须服务器端必须向 mongodb 请求数据,这与所有此类连接的数量相同。这就是它变慢的原因。

      最后我添加了redis.io

      meteor npm install --save redis
      meteor npm install --save hiredis
      

      在服务器端:

      import { Meteor } from "meteor/meteor";
      
      var redis = require("redis");
      var clientRedis = redis.createClient({
          host: "YOURREDIS_IP",
          port: "YOURREDIS_PORT"
      });
      clientRedis.setSync = Meteor.wrapAsync(clientRedis.set);
      clientRedis.getSync = Meteor.wrapAsync(clientRedis.get);
      
      setRedis_Object = function (keyREDIS, timeRefresh, valueREDIS) {
          return clientRedis.setSync(keyREDIS + moment(new Date()).format(timeRefresh), JSON.stringify(valueREDIS));
      };
      
      getRedis_Object = function (keyREDIS, timeRefresh) {
          return JSON.parse(clientRedis.getSync(keyREDIS + moment(new Date()).format(timeRefresh)));
      };
      
      Meteor.methods({
          getRedis_YOURCOLLECTIONS: function(timeRefresh) {
               var data = getRedis_Object(getRedis_YOURCOLLECTIONS, timeRefresh);
               if (data != null) {
                    return data;
               } else {
                    var data = YOURCOLLECTIONS.find().fetch();
                    setRedis_Object(key, timeRefresh, data);
                    return data
               }
          },
      });
      

      在客户端

        Meteor.call("getRedis_YOURCOLLECTIONS", "YYYYMMDD", function (error, result) {
            if (error) {
                console.log(error);
            } else {
                Session.set("getRedis_YOURCOLLECTIONS", result);
            }
        });
      

      在我在服务器上添加此 REDIS 消耗内存和 CPU 后,应用程序速度更快。我希望它对你有用。谢谢

      【讨论】:

      • 哇,太好了!你在哪里安装了你的 redis,你是如何将数据存储到 redis 中的?谢谢
      • 最好的区别服务器与数据库,但在本地网络与服务器端客户端。我已经将 Mongodb 和 Redis 与 DOCKER 一起使用。它运作良好。 redis 是内存数据结构存储,如您所见,“setRedis_Object”是将数据存储到 redis 键的函数。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-17
      • 2015-10-29
      • 2022-07-28
      • 1970-01-01
      • 2020-07-22
      • 2014-10-15
      相关资源
      最近更新 更多