Page 1 sur 1

Accélérer le chargement d'images

Posté : 09 oct. 2021, 14:52
par Herve_be
Bonjour,
Une de mes pages est un album photo : en php il va chercher les 750 images d'un répertoire et les classe par date (données Exif) avant de les afficher en miniature.
Problème : si on clique sur une image avant qu'elles soient toutes chargées, ce qui prend environ 30 secondes, cette image est affichée en grand dans la même fenêtre; quand on la quitte il revient à la fenêtre précédente et ... recharge les images !
Voici l'essentiel du code
<head>
<script type="text/javascript" language="javascript" src="../../lytebox.js"></script>
<link rel="stylesheet" href="../../lytebox.css" type="text/css" media="screen" >
</head>
<?php
$localURL = 'Temp.jpeg';
$dir = opendir("Photos");
while($file = readdir($dir))
  {
  if(substr($file,-3)=="jpg")
	{
	copy("Photos/".$file, $localURL);
	$exif_data = @exif_read_data($localURL,0,true);
	$Date=$exif_data['EXIF']['DateTimeDigitized'];
 	$Date=substr($Date,8,2)."/".substr($Date,5,2)."/".substr($Date,0,4);
	$Time=mktime(0,0,0,(int)substr($Date,3,2),(int)substr($Date,0,2),(int)substr($Date,-4));
	$Delta=floor(time()/24/60/60)-floor($Time/24/60/60);	//Différence en jours entre aujourd'hui et date fichier
	$Delta=str_pad($Delta, 5, "0", STR_PAD_LEFT);
	$dat[] = $Delta.str_pad(substr($file,0,strlen($file)-4), 3, "0", STR_PAD_LEFT).$Date;	// DDDDDfffYYYY/MM/DD
	}
  }
sort($dat);	//Tri selon la date décroissante (âge croissant) et nom de fichier croissant
foreach($dat as $elem)
	{	// je vous passe la mise en page sous forme de tableau
	Echo "<a href='Photos/".$File.".jpg' rel='lyteshow[PPAlbum]'><img src='Photos/".$File.".jpg' width='120'></a>";
	}
lytebox.js est un script qui permet d'afficher chaque image dans une "boîte" munie de flèches pour les faire défiler.
Pour accélérer l'affichage, est-il possible de charger les images en miniature ou en faible résolution et de ne pas charger l'image complète avant qu'on clique dessus ?
Autres suggestions pour accélérer le chargement sont bienvenues.
Merci d'avance pour votre aide

Re: Accélérer le chargement d'images

Posté : 09 oct. 2021, 21:32
par @rthur
Voici quelques pistes d'optimisation :
:arrow: 1) rechercher à chaque appel les données exif de chaque image pour ensuite faire un tri est très gourmand en ressource.
Mon conseil serait que ton script renomme tes fichiers en ajoutant la date Exif au format YmdHi en début du nom, comme ça ensuite un simple affichage par ordre alphabétique (via la fonction glob() par exemple) te retournera immédiatement les fichiers dans le bon ordre.

:arrow: 2) Indiquer dans ton htaccess des consignes de mise en cache via l'entête (une expiration de 31536000 secondes correspond à 1 an)

Code : Tout sélectionner

<FilesMatch "\.(?i:gif|jpe?g|png)$"> Header set Cache-Control "max-age=31536000, public" </FilesMatch>
:arrow: 3) Utiliser un CDN, par exemple Cloudflare, dont l'offre gratuite est suffisante dans une grande majorité des cas :
https://www.cloudflare.com/plans/

:arrow: 4) Afficher effectivement des images redimensionnées préalablement à la bonne taille/qualité. Ce conseil est valable pour ton affichage en liste avec des miniatures, mais aussi pour ton affichage en plein écran. Si c'est juste pour un affichage et pas pour une impression, il est souvent préférable de réduire la taille à un format HD (1920x1080px) plutôt que de la garder dans sa résolution d'origine qui peut parfois être très importante en terme de poids de fichier notamment si ces photos viennent d'un appareil photo.
PHP a la fonction imagecopyresized() qui pourra t'aider, mais je te conseille de passer par une librairie qui gère les cas particuliers.
Voici une librairie qui pourra t'aider : https://github.com/gumlet/php-image-resize

:arrow: 5) Le script JS que tu utilises pour ta galerie a eu sa dernière mise à jour en 2007, ça fait donc 14 ans... une éternité pour un développement web... L'arrivée de HTML5 et CSS3 ont permis aussi beaucoup d'amélioration donc ça vaudrait peut-être le coup de regarder les scripts + récents pour gagner en performance.
Voici quelques exemples issus d'une rapide recherche Google :
https://www.lightgalleryjs.com
ou sinon
https://nanogallery2.nanostudio.org
qui a même un plugin PHP pour faire le redimensionnement automatique :
https://nanophotosprovider2.nanostudio.org

Re: Accélérer le chargement d'images

Posté : 09 oct. 2021, 22:02
par two3d
Problème : si on clique sur une image avant qu'elles soient toutes chargées, ce qui prend environ 30 secondes, cette image est affichée en grand dans la même fenêtre; quand on la quitte il revient à la fenêtre précédente et ... recharge les images !
C'est du au fait que le script de galerie n'est pas encore chargé et que l'image s'ouvre comme un lien href basique.

Tu peux laisser le chargement et cliquer sur l'image si tu rajouter un target="_blank" à ta balise <a> (<a href='Photos/".$File.".jpg' rel='lyteshow[PPAlbum]'>)

Code : Tout sélectionner

type="text/javascript" language="javascript"
N'est plus obligatoire, simplement ceci fonctionne tout autant:

Code : Tout sélectionner

<script src="scripts.js"></script>

Re: Accélérer le chargement d'images

Posté : 10 oct. 2021, 15:30
par Herve_be
Merci pour vos réponses, quelques commentaires
1) rechercher à chaque appel les données exif de chaque image pour ensuite faire un tri est très gourmand en ressource.
Mon conseil serait que ton script renomme tes fichiers en ajoutant la date Exif au format YmdHi en début du nom, comme ça ensuite un simple affichage par ordre alphabétique (via la fonction glob() par exemple) te retournera immédiatement les fichiers dans le bon ordre.
Ajouter la date dans l'array est ce que je fais pour trier
$dat[] = $Delta.str_pad(substr($file,0,strlen($file)-4), 3, "0", STR_PAD_LEFT).$Date;	// DDDDDfffYYYY/MM/DD
modifier le nom des fichiers est une meilleure idée, à condition de ne le faire qu'une fois pour chaque fichier (le nom du fichier indique s'il a déjà été modifié).
2) Indiquer dans ton htaccess des consignes de mise en cache via l'entête (une expiration de 31536000 secondes correspond à 1 an)
Il y a déjà quelque chose du genre

Code : Tout sélectionner

ExpiresByType image/jpeg "access plus 1 year"
3) Utiliser un CDN, par exemple Cloudflare, dont l'offre gratuite est suffisante dans une grande majorité des cas :
https://www.cloudflare.com/plans/
Je ne comprends pas à quoi sert un CDN.
4) Afficher effectivement des images redimensionnées préalablement à la bonne taille/qualité. Ce conseil est valable pour ton affichage en liste avec des miniatures, mais aussi pour ton affichage en plein écran. Si c'est juste pour un affichage et pas pour une impression, il est souvent préférable de réduire la taille à un format HD (1920x1080px)
Les grandes images sont déjà redimensionnées à 1200 x 800.
J'ai ajouté un répertoire Thumbnail dans lesquelles les mêmes images sont à 120 x 80 : ça va déjà nettement plus vite !
5) Le script JS que tu utilises pour ta galerie a eu sa dernière mise à jour en 2007, ça fait donc 14 ans... une éternité pour un développement web... L'arrivée de HTML5 et CSS3 ont permis aussi beaucoup d'amélioration donc ça vaudrait peut-être le coup de regarder les scripts + récents pour gagner en performance.
Voici quelques exemples issus d'une rapide recherche Google :
https://www.lightgalleryjs.com
ou sinon
https://nanogallery2.nanostudio.org
qui a même un plugin PHP pour faire le redimensionnement automatique :
https://nanophotosprovider2.nanostudio.org
Je regarderai à l'occasion, j'utilise ce sript dans de nombreuses pages sur mon site.
Problème : si on clique sur une image avant qu'elles soient toutes chargées, ce qui prend environ 30 secondes, cette image est affichée en grand dans la même fenêtre; quand on la quitte il revient à la fenêtre précédente et ... recharge les images !
C'est du au fait que le script de galerie n'est pas encore chargé et que l'image s'ouvre comme un lien href basique.
Tu peux laisser le chargement et cliquer sur l'image si tu rajouter un target="_blank" à ta balise <a> (<a href='Photos/".$File.".jpg' rel='lyteshow[PPAlbum]'>)
En effet, si on clique sur une photo avant que la page ne soit complètement chargée cette photo s'ouvre dans un nouvel onglet et la page de miniatures continue à se charger.
Par contre le comportement devient bizarre.

Code : Tout sélectionner

type="text/javascript" language="javascript"
N'est plus obligatoire, simplement ceci fonctionne tout autant:

Code : Tout sélectionner

<script src="scripts.js"></script>
Y a-t-il un avantage à supprimer

Code : Tout sélectionner

type="text/javascript" language="javascript"
?

Re: Accélérer le chargement d'images

Posté : 10 oct. 2021, 18:29
par two3d
J'ai ajouté un répertoire Thumbnail dans lesquelles les mêmes images sont à 120 x 80 : ça va déjà nettement plus vite !
Parfait!
Y a-t-il un avantage à supprimer

Code : Tout sélectionner
type="text/javascript" language="javascript"
Si ça t'embête pas d'écrire à chaque fois type="text/javascript" language="javascript" pour rien, vasy ;)

Re: Accélérer le chargement d'images

Posté : 11 oct. 2021, 11:49
par @rthur
3) Utiliser un CDN, par exemple Cloudflare, dont l'offre gratuite est suffisante dans une grande majorité des cas :
https://www.cloudflare.com/plans/
Je ne comprends pas à quoi sert un CDN.
Un CDN est un ensemble de serveurs disposé partout sur la planète et qui met en cache les images (dans ton cas) au plus proche des utilisateurs pour pouvoir leur envoyer ultra-rapidement.