当实例化mongoose模型时,应用程序会变慢

时间:2017-03-10 15:03:55

标签: node.js mongodb express mongoose

我正在开发购物车作为我学习的一部分。我面临的问题是,无论何时将物品添加到购物车,加载时间都会大幅增加(基准测试如下),并且当购物车为空时会恢复正常。

基准
当购物车为空时:加载时间低于1秒。

GET / 304 154.242 ms - -
GET /stylesheets/bootstrap.css 304 81.079 ms - -
GET /stylesheets/style.css 304 79.363 ms - -
GET /fonts/font-awesome/css/font-awesome.min.css 304 84.550 ms - -
GET /product/58c179fb2148643f5865d4ca/image 304 86.347 ms - -
GET /product/58c151f95b18373990f1c714/image 304 113.943 ms - -
GET /product/58c17c9e32f18e2eb86fbd44/image 304 120.220 ms - -
GET /product/58c17ced9697ec3e44bba381/image 304 82.483 ms - -
GET /product/58c210c5e5ca5b2298724b77/image 304 83.583 ms - -
GET /fonts/font-awesome/fonts/fontawesome-webfont.woff2?v=4.7.0 304 15.826 ms - -

当商品在购物车中时:加载时间平均为10秒。

GET / 304 3441.581 ms - -
GET /stylesheets/bootstrap.css 304 17074.679 ms - -
GET /stylesheets/style.css 304 18020.767 ms - -
GET /fonts/font-awesome/css/font-awesome.min.css 304 19067.181 ms - -
GET /product/58c17c9e32f18e2eb86fbd44/image 304 13065.619 ms - -
GET /product/58c151f95b18373990f1c714/image 304 15917.767 ms - -
GET /product/58c179fb2148643f5865d4ca/image 304 22550.998 ms - -
GET /product/58c17ced9697ec3e44bba381/image 304 23376.352 ms - -
GET /product/58c210c5e5ca5b2298724b77/image 304 20143.963 ms - -
GET /fonts/font-awesome/fonts/fontawesome-webfont.woff2?v=4.7.0 304 4767.430 ms - -

以下代码是最低限度的实施:

模型/ product.js

var schema = new Schema({
  image: {data: Buffer, contentType: String},
  title: {type: String, required: true},
  description: {type: String, required: true},
  price: {type: Number, required: true}
});
module.exports = mongoose.model('Product', schema);

模型/ cart.js

module.exports = function Cart(oldCart) {
// associative array
  this.items = oldCart.items || {};

  this.add = function(product) {
// if item is not in cart => assign argument to product properties
    if(!this.items[product._id])
      this.items[product._id] = {product: product, qty: 0, price: 0};
// if item is already in cart => just increase the qty and price
    this.items[product._id].qty++;
    this.items[product._id].price += product.price;
  }


  this.removeItems = function (productId) {
    delete this.items[productId];
  }
}

路由/ cart.js

router.get('/add-to-cart/:id', function (req, res, next) {
  var productId = req.params.id;
// req.session from: express-session module
  var cart = new Cart(req.session.cart);

  Product.findById(productId, function (err, product) {

    cart.add(product);

    req.session.cart = cart;
    res.redirect('/');
  });
});


router.get('/remove/:id', function (req, res, next) {
  var productId = req.params.id;
  var cart = new Cart(req.session.cart);

  cart.removeItems(productId);

  req.session.cart = cart;
  res.redirect('/cart');
});

尝试:
我曾尝试将不需要的对象设置为null,因为我猜测内存可能会泄漏到某处。问题仍然存在。

产品图片不超过16MB,因此我将它们作为BinaryData存储在mongo中。我真的不知道加载时间是如何增加的。每个建议都表示赞赏。我愿意编辑帖子以提供更多信息。

1 个答案:

答案 0 :(得分:1)

您的问题可能是由于您在按ID找到产品时加载了图片缓冲区。

...
image: {data: Buffer, contentType: String},
...

由于您在添加到购物车时不需要该信息,因此在您按ID查找时,请告诉mongo不要返回该字段。

Product.findById(productId).select('-image').exec(function(){})

然后,当有人看到他们的购物车时,可能会再次要求检索图像。

修改

确保在检索图像时也缓存图像。这将确保您的服务器可以快速提供图像。

请参阅apicache,它应该能够满足您的需求。

在客户端,您可能需要确保您的图像也在那里缓存(这可能已经自动发生)。

编辑2: 我相信这样的事情应该适合你的apicache。你可能需要调整一下。

var apicache = require('apicache');
let cache = apicache.middleware;

...

app.get('/image/:productId', cache('1 hour'), function(req, response) {
  var buffer = ""; //get the image buffer from mongo

  //return to client
  response.writeHead(200, {
    'Content-Type': 'image/jpeg' //Or whatever filetype its supposed to be... png, gif etc
  });
  response.write(buffer);
  response.end();
});

...