我正在开发购物车作为我学习的一部分。我面临的问题是,无论何时将物品添加到购物车,加载时间都会大幅增加(基准测试如下),并且当购物车为空时会恢复正常。
基准
当购物车为空时:加载时间低于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中。我真的不知道加载时间是如何增加的。每个建议都表示赞赏。我愿意编辑帖子以提供更多信息。
答案 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();
});
...