Pourquoi ma solution est si lente et comment puis-je améliorer les performances de la requête?

Actuellement, j'ai pu optimiser les performances un peu, mais c'est encore un peu lent: /

DERNIÈRE EDIT:

Ma solution actuelle (l'atm le plus rapide (mais encore lent) et conserve l'ordre):

serveur

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); } }); }); 

Requête client

 $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; }); }) }); }; 

Client 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> 

Votre solution est lente car vous téléchargez les images de votre Cloud Storage et vous les utilisez sur votre propre serveur. Vous obtenez un délai sur le téléchargement et le téléchargement, une surcharge de ~ 33% en utilisant des données encodées base64, plus votre serveur est tendu dans la livraison d'images au lieu de se concentrer sur la livraison du contenu de votre site.

Comme l'ont souligné plusieurs des commentaires, la meilleure solution consiste à utiliser l'URL publique pour les images:

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

En utilisant l'URL publique, vous utilisez directement Cloud Cloud en profitant de l'infrastructure de service globale de Google . Et l'application ne doit pas répondre aux demandes d'images, libérer des cycles de CPU pour d'autres demandes.

Si vous ne souhaitez pas que les robots gèlent vos images en utilisant la méthode ci-dessus, Google recommande d'utiliser un fichier robots.txt pour bloquer l'accès à vos images.

  1. Avant d'optimiser, vous devriez mieux collecter des données, j'en montrerai l'extrait suivant
  2. On dirait que base64_encode(contents) peut coûter beaucoup de CPU, votre logique semble faire plusieurs fois cela. Cela suppose, le véritable goulet d'étranglement que vous devez trouver par vous-même
  3. D'autres suggestions peuvent faire moins d'amélioration, mais cela aura un effet total (gzip \ CDN \ http2 \ loadbalance …)

Optimisation Data Collect – Server Side, quelle opération a pris trop de temps

 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); } }); }); 

Le moyen le plus simple d'optimiser votre code est d'envoyer une requête ajax unique sur le serveur, plutôt que d'effectuer une requête ajax pour chacune des images.

Supprimez les appels ajax de la boucle. Faites une boucle dans la collection, rassemblez les données que vous devez envoyer au serveur dans un tableau, puis envoyez-le via une seule requête ajax. Cela accélérera les choses.

De plus, assurez-vous de modifier votre gestionnaire POST côté serveur afin qu'il puisse gérer le tableau, vous allez passer du client.

Je ne sais pas comment augmenter la vitesse des fichiers livrés, mais le problème d'être hors service est qu'ils sont asynchrones. Fondamentalement, ce qui se passe, c'est que vous dites au serveur de vous fournir un tas de fichiers, puis vous attendez. Une fois que le serveur les envoie, vous les manipulez. Mais vous ne connaissez pas l'ordre dans lequel ils arrivent. Ce que vous devez faire, c'est garder une trace de l'ordre à l'arrivée. La façon de le faire est d'avoir un moyen de suivre les informations sur chaque publication. Par exemple, disons que vous avez

 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 } }) } 

Cela devrait configurer correctement les valeurs. La syntaxe pourrait être un peu désactivée, mais je crois que c'est la bonne idée de les configurer dans l'ordre correct. La partie importante est de définir le contexte, qui définira ce que «ceci» est égal au gestionnaire de réussite