web-dev-qa-db-fra.com

Accélérez le téléchargement d'images multiples sur le site Web à partir du navigateur client vers le serveur

Je comprends qu'il existe des moyens de télécharger plusieurs images d'un navigateur à un serveur et que la vitesse de téléchargement dépend de la vitesse du serveur et du réseau. La façon habituelle de le faire:

Cliquez sur un bouton de téléchargement sur le site Web -> choisissez les images que vous souhaitez télécharger -> cliquez sur le bouton Soumettre pour télécharger toutes les images sur le serveur (Invite "veuillez patienter" pour l'utilisateur) -> Téléchargement réussi!

Mais en ce qui concerne le codage, je me demandais simplement s'il existait un moyen plus rapide de télécharger efficacement des images du périphérique du client vers le serveur. (Utiliser Javascript et php)

Actuellement, ce que je fais est tout d'abord de "couper" les images du côté client, puis de les renvoyer au serveur. Mais cela est très lent car javascript prend du temps pour "réduire" la taille des images. Par "couper", j'entends réduire la largeur et la hauteur de l'image. Y a-t-il un moyen plus rapide de le faire?

(Quelques exemples de codage javascript et php pourraient également aider.)

18
Ryan Fung

Réponse courte: Non , Javascript n'est pas lent, ni PHP.

Si l'image est grande (quelques mégaoctets), il faudra un moment pour rogner/redimensionner l'image en javascript/php. Il n'y a aucun moyen de l'éviter.

Je crois que vous rencontrez un problème de performances pour les raisons suivantes:

  1. Vous téléchargez plusieurs} images à la fois, et ..
  2. Certains sont gros (en mégaoctets)

Pensez à optimiser les images avant de les télécharger. Je vous suggère d'utiliser kraken.io , que vous pouvez réduire la taille des images sans changer la qualité de l'image ( loseless mode).

En outre, envisagez de télécharger des images par morceaux, qui:

  1. Vous permet de suivre la progression du téléchargement
  2. Conduit par AJAX

Il existe de nombreux plugins de téléchargement de morceaux, en voici un:

https://github.com/blueimp/jQuery-File-Upload/wiki/Chunked-file-uploads

Enfin, regardez kraken.io lui-même, vous apprendrez peut-être peu de choses sur la façon d’accélérer le téléchargement d’images.

6
evilReiko

Essayons de relever ce défi systématiquement! Votre tâche est aussi simple que cela: envoyer X octets de l’ordinateur de l’utilisateur au serveur Y le plus rapidement possible. Supposons qu'une fois que les données arrivent sur le serveur, le temps de traitement est négligeable - tout serveur moderne peut traiter les grandes images très rapidement.

Nous pouvons diviser les solutions possibles en deux catégories:

  1. Diminuer le X - diminuer la quantité de données envoyées. Réduisez l'image côté utilisateur en JavaScript et envoyez des images plus petites au serveur Y.

  2. Déplacez le serveur Y plus près de l'utilisateur (étonnamment personne n'a mentionné cela?) Il n'est pas nécessaire de déployer plusieurs serveurs dans le monde, vous pouvez simplement utiliser un CDN (et beaucoup d'entre eux sont gratuits ou très bon marché aujourd'hui). Même si CDN frappe toujours votre serveur Web à la fin, il est généralement prudent de supposer que les fournisseurs de CDN ont une bande passante internationale supérieure à celle d'un utilisateur moyen.

Notes supplémentaires:

  1. Faites des tests de vitesse, votre serveur actuel peut avoir des problèmes de bande passante et les images sont téléchargées bien plus lentement qu’elles ne le devraient. En déplaçant simplement le site vers une autre société d'hébergement, vos téléchargements d'images pourraient devenir plus rapides.

  2. En fonction de votre application UX, vous pouvez améliorer la vitesse perçue par l'utilisateur en affichant les vignettes des images dès que les fichiers sont sélectionnés (effectué côté JS), alors que les fichiers sont toujours en cours de téléchargement. Vous pouvez même permettre à l'utilisateur de parcourir la page ou le site pendant le téléchargement. Si vous ne bloquez pas l'interface utilisateur, les téléchargements lents sont moins gênants.

En général, c'est une question complexe et il n'y a pas une seule approche - c'est un ensemble d'étapes. Et si un utilisateur a une connexion terrible, rien d’autre n’a d’importance!

3
Denis Mysenko

Auparavant, je devais résoudre un problème similaire, même si ma solution consistait à optimiser les images côté client, ce que vous avez prétendu être lent. Comme ma propre expérience dit le contraire, je voudrais savoir quelles solutions avez-vous déjà essayées.

Ma solution était:

  1. Lisez les images côté client à l'aide de FileReader API . Semble que ce n'est pas nécessaire.
  2. Optimisez chaque image en mettant à l'échelle et en définissant la qualité, à l'aide de Canvas API . Si, pour une raison quelconque, ce processus s'avère lent, vous pouvez toujours utiliser la API WebWorkers pour fractionner la charge en plusieurs processus en arrière-plan. L'avantage est que les problèmes de performances liés au processus d'optimisation n'affecteront pas votre interface utilisateur (ne la bloqueront pas).
  3. Fusionnez toutes les images en un seul Sprite, en utilisant également Canvas, et enregistrez les métadonnées du Sprite (chaque image: x, y, largeur, hauteur) dans un objet séparé.
  4. Extrayez le base64 du Sprite à l’aide de Canvas toDataURL.
  5. Téléchargez le fichier Sprite compressé sur le serveur avec les métadonnées du Sprite. Sur le serveur, décompressez le fichier, puis divisez-le et enregistrez-le dans des fichiers images distincts en fonction des métadonnées.

Cela devrait permettre d’utiliser le client, ce qui, dans la plupart des cas, réduira votre utilisation du réseau et vos besoins en bande passante.

Mise à jour:

Voici un exemple de code } pour le code côté client. Vous sélectionnez autant de fichiers que vous le souhaitez dans le champ de saisie. Par la suite, seules les images sont sélectionnées, redimensionnées, emballées dans un Sprite et exportées sous forme d'objet contenant la version base64 du Sprite et les métadonnées de chaque image qu'il contient. J'ai rendu les données base64 cliquables pour que vous puissiez voir les résultats immédiatement.

Ce qui manque, c'est la partie serveur, dans laquelle vous prenez l'objet et l'utilisez. Vous créez une image en utilisant les données base64 uri, je suggère d'utiliser imagemagick , mais une telle bibliothèque ferait l'affaire, puis vous rognez vos images, en utilisant la bibliothèque que vous avez choisie, en fonction des métadonnées du Sprite et enregistrez chaque image séparément (ou autre).

Vous pouvez effectuer de nombreuses optimisations, petites mais intéressantes, côté client, afin de réduire la charge sur vos serveurs.

2
iMoses

Non, le téléchargement sera toujours lent. La vitesse n'a pratiquement rien à voir avec le code. La lenteur tient au fait que les images peuvent prendre beaucoup de place. Habituellement jusqu'à plusieurs mégaoctets. Si vous deviez télécharger une chaîne de texte à des fins de comparaison, ce serait beaucoup plus rapide, car cette chaîne de texte ne contient que quelques octets ou kilo-octets. Pour accélérer un peu ce processus, il suffit de placer l’image dans un dossier compressé .Zip avant de la télécharger sur le serveur. Cela prendrait quand même très longtemps.

2
OneStig
  1. Lorsque les images d'origine sont téléchargées, les gains d'optimisation seront probablement insignifiants, sauf si vos utilisateurs téléchargent un *.bmp non compressé. Si vous redimensionnez des images localement, assurez-vous que la compression appropriée a été appliquée - définissez au moins toDataURLencoderOptions lorsque vous utilisez un canevas ou quelque chose comme: JIC ( demo ). Attention à la mauvaise qualité de ré-échantillonnage.

  2. Si vous vous attendez à des envois massifs ou à des utilisateurs à faible bande passante, vous pouvez introduire des envois pouvant être repris. Une bibliothèque telle que resumablejs utiliserait une api de fichier html5 et prendrait en charge la fragmentation, ce qui rendait le processus de téléchargement moins pénible pour les connexions médiocres. C'est un combo assez puissant lorsqu'il est associé à des améliorations UX!

  3. Plutôt que de vous concentrer sur les performances de téléchargement, vous pouvez obtenir de meilleurs résultats en vous concentrant sur la perception des performances. Un motif utile consiste à déplacer le téléchargement vers une étape précédente du flux de travail - Instagram commence un téléchargement dès que l'image a été sélectionnée et continue en arrière-plan pendant que l'utilisateur travaille sur la légende, l'emplacement, les options de partage ...

    Plus de pensées de Diapositives "Des secrets pour Lightning Fast Mobile Design" résumées sur haute résolution :

    https://speakerdeck.com/mikeyk/secrets-to-lightning-fast-mobile-design?slide=82

    Déplace les bits lorsque personne ne regarde. Le téléchargement des images commence avant vous les partagez, la plupart des applications attendent après l'écran de partage. La règle est d'envoyer les données dès qu'elles sont prêtes, puis de les faire correspondre aux actions de l'utilisateur ultérieurement. Cela double le nombre de demandes, mais les performances perçues sont améliorées, même si une annulation est envoyée ultérieurement. Les données sont supprimées lors d'une annulation.

  4. Télécharger sur un CDN. Stackoverflow s’intègre à imgur pour les téléchargements d’images et vous le pouvez aussi . Bien sûr, cela dépend de la sensibilité des téléchargements, de la fonctionnalité attendue et des conditions générales de CDN, mais vous économiserez du trafic et du stockage tout en fournissant un accès api spécialisé aux images originales, aux copies redimensionnées et aux métadonnées supplémentaires.

2
o.v.

C'est une excellente solution car elle réduit la taille de l'image avant le téléchargement.

https://github.com/blueimp/jQuery-File-Upload

Vous n'avez pas indiqué si vous étiez opposé à l'utilisation de jQuery. Si vous l'êtes, vous pourrez peut-être trouver une solution équivalente en JavaScript pur.

0
user2182349

Je pense que même si vous trouvez un meilleur algorithme d'optimisation à la fin de la journée si nous parlons de téléphones mobiles, vous devriez considérer que le réseau pourrait être assez lent, de même que le processeur. Ma suggestion est d'essayer les travailleurs Web et il y a ce tutoriel pourrait être très utile.

Les travailleurs Web exécutent des scripts en arrière-plan indépendamment de l'interaction de l'utilisateur, ce qui peut s'avérer très utile pour éviter tout impact sur l'utilisateur et pour gérer le traitement et le chargement des images en arrière-plan.

Deux avantages principaux:

  • vous pouvez exécuter plusieurs threads/travailleurs Web en parallèle
  • les travailleurs Web ne bloquent pas le fil principal et l'expérience utilisateur

Est-ce que des avantages pourraient non seulement accélérer le traitement de l'image, mais éviter globalement de geler l'interface utilisateur.

0
Davide Ungari