为什么我的解决scheme如此之慢以及如何提高查询的性能?

目前我能够优化性能相当多,但它仍然有点慢:/

最新编辑:

我目前的解决scheme(最快的ATM(但仍然缓慢),并保持秩序):

服务器

router.post('/images', function(req, res, next) { var image = bucket.file(req.body.image); image.download(function(err, contents) { if (err) { console.log(err); } else { var resultImage = base64_encode(contents); var index = req.body.index; var returnObject = { image: resultImage, index: index } res.send(returnObject); } }); }); 

客户端查询

 $scope.getDataset = function() { fb.orderByChild('id').startAt(_start).limitToFirst(_n).once("value", function(dataSnapshot) { dataSnapshot.forEach(function(childDataSnapshot) { _start = childDataSnapshot.child("id").val() + 1; var post = childDataSnapshot.val(); var image = post.image; var imageObject = { image: image, index: position }; position++; $.ajax({ type: "POST", url: "images", data: imageObject, }).done(function(result) { post.image = result.image; $scope.data[result.index] = post; $scope.$apply(); firstElementsLoaded = true; }); }) }); }; 

客户端HTML

 <div ng-controller="ctrl"> <div class="allcontent"> <div id="pageContent" ng-repeat="d in data track by $index"><a href="details/{{d.key}}" target="_blank"><h3 class="text-left">{{d.title}}<a href="../users/{{d.author}}"><span class="authorLegend"><i> by {{d.username}}</i></span></a></h3> </a> <div class="postImgIndex" ng-show="{{d.upvotes - d.downvotes > -50}}"> <a href="details/{{d.key}}" target="_blank"><img class="imgIndex" ng-src="data:image/png;base64,{{d.image}}"></a> </div> <div class="postScore">{{d.upvotes - d.downvotes}} HP</div> </div> </div> </div> 

您的解决scheme很慢,因为您正在从您的云端存储中下载映像,并在您自己的服务器上提供这些映像。 你下载和上传的时间会延迟,使用base64编码数据的开销会增加33%,而且你的服务器在传输图像方面很紧张,而不是专注于提供你的网站内容。

正如许多评论所指出的,最佳实践解决scheme是使用图像的公共URL,如下所示:

 function getPublicUrl (filename) { return "https://storage.googleapis.com/${CLOUD_BUCKET}/${filename}"; } 

通过使用公共URL,您可以直接从云存储服务中 利用Google的全球服务基础架构 。 而且应用程序不必响应图像请求,释放其他请求的CPU周期。

如果您不希望漫游器使用上述方法抓取您的图片,Googlebuild议您使用robots.txt文件阻止访问您的图片。

  1. 在优化之前,您最好收集一些数据,我会在下面的代码片段中展示一些数据
  2. 看起来像base64_encode(contents)可能会花费很多CPU,你的逻辑似乎反复做这个。 这是猜测,你必须find自己的瓶颈
  3. 其他的build议可能会减less改进,但是总的来说效果会非常好(gzip \ CDN \ http2 \ loadbalance …)

优化数据收集 – 服务器端,哪个操作花费太多时间

 router.post('/images', function(req, res, next) { var d = new Date() var image = bucket.file(req.body.image); image.download(function(err, contents) { console.log('download:' + new Date() - d) if (err) { console.log(err); } else { var resultImage = base64_encode(contents); console.log('base64_encode:' + new Date() - d) var index = req.body.index; var returnObject = { image: resultImage, index: index } res.send(returnObject); } }); }); 

优化代码最简单的方法是向服务器端发送一个ajax请求,而不是为每个图像执行一个ajax请求。

从循环中删除ajax调用。 循环访问集合,将需要发送到服务器的数据收集到一个数组中,然后通过一个Ajax请求发送。 这会加快速度。

此外,请确保修改您的服务器端POST处理程序,以便它可以处理该数组,您将从客户端传递。

我不确定如何提高交付的文件的速度,但是它们出现问题的原因是它们是asynchronous的。 基本上,发生的是你告诉服务器给你一堆文件,然后等待。 一旦服务器发送给你,你处理它们。 但是你不知道他们进来的顺序。 你需要做的是跟踪他们到达的顺序。 做到这一点的方法是有一些跟踪每个职位信息的方式。 例如,让我们说你有

 var arr = new Array(10); for (var i = 0 ; i < arr.length; i++){ $.ajax({ url:____, type:"GET" (or whatever type you want), data: _____, context: {index: i} success : function(data){ arr[this.index] = data } }) } 

这应该正确设置值。 语法可能有点偏离,但我相信这是正确的想法,以正确的顺序设置它们。 重要的部分是设置上下文,这将设置成功处理程序中的“this”等于什么