En cache, les miniatures générées par PHP se chargent lentement


179

Question Partie A ▉ (100 primes, attribuées)
La question principale était de savoir comment rendre ce site, charger plus rapidement. Nous devions d'abord lire ces cascades. Merci à tous pour vos suggestions sur l'analyse de lecture de la cascade. Le principal goulot d'étranglement se dégage des différents graphiques en cascade montrés ici: les vignettes générées par PHP. Le chargement de jquery sans protocole à partir de CDN conseillé par David a obtenu ma prime, bien que mon site ne soit globalement que 3% plus rapide, et sans répondre au principal goulot d'étranglement du site. Il est temps de clarifier ma question et, une autre prime:

Question Partie B ▉ (100 bountys, attribués)
Le nouvel objectif était maintenant de résoudre le problème des 6 images jpg, qui causent le plus de retard de chargement. Ces 6 images sont des miniatures générées par PHP, minuscules et seulement 3 ~ 5 ko, mais se chargent relativement très lentement. Remarquez le " temps jusqu'au premier octet " sur les différents graphiques. Le problème est resté non résolu, mais une prime est allée à James, qui a corrigé l'erreur d'en-tête que RedBot a souligné : "Une demande conditionnelle If-Modified-Since a renvoyé le contenu complet inchangé." .

Question Partie C ▉ (ma dernière prime: 250 points)
Malheureusement, même après que l'erreur d'en-tête REdbot.org ait été corrigée, le retard causé par les images générées par PHP est resté intact. Que diable pensent ces minuscules miniatures miniatures de 3 ~ 5Kb? Toutes ces informations d'en-tête peuvent envoyer une fusée sur la lune et inversement. Toute suggestion sur ce goulot d'étranglement est très appréciée et traitée comme une réponse possible, car je suis coincé à ce problème de goulot d'étranglement depuis déjà sept mois maintenant. Merci d'avance.

[Quelques informations de fond sur mon site: CSS est en haut. JS en bas (Jquery, JQuery UI, menu acheté moteurs awm / menu.js, moteur tabs js, vidéo swfobject.js) Les lignes noires sur la deuxième image montrent ce qui déclenche quoi charger. Le robot en colère est mon animal de compagnie "ZAM". Il est inoffensif et souvent plus heureux.]


Load Waterfall: chronologique | http://webpagetest.org entrez la description de l'image ici


Domaines parallèles groupés | http://webpagetest.org entrez la description de l'image ici


Cascade Site-Perf | http://site-perf.com entrez la description de l'image ici


Pingdom Tools Waterfall | http://tools.pingdom.com

entrez la description de l'image ici


Cascade GTmetrix | http://gtmetrix.com

entrez la description de l'image ici



11
Je pense que la plupart des navigateurs ne font que 20 connexions à la fois, donc après 20, le premier doit se terminer avant le prochain démarrage, d'où le ralentissement après 20

1
Je pense que vous avez oublié de biffer la première instance de votre domaine. Au moins, vous avez le reste d'entre eux: D
thirtydot

2
Ne pouvez-vous pas combiner certaines de ces images en sprites?
Marcel Korpel

1
@Dagon, sachez que HTTP 1.1 RFC demande ( SHOULD) aux clients HTTP 1.1 d'utiliser au plus 2 connexions aux serveurs HTTP 1.1; HTTP 1.0 est bien sûr beaucoup plus ouvert.
sarnold

1
Les navigateurs @Dagon ne feront également que 2 connexions simultanées à un domaine donné.
Endophage

Réponses:


61

Tout d'abord, l'utilisation de ces multiples domaines nécessite plusieurs recherches DNS. Vous feriez mieux de combiner plusieurs de ces images dans un sprite au lieu de diffuser les demandes.

Deuxièmement, lorsque je charge votre page, je vois la plupart des blocages (~ 1,25 s) sur all.js. Je vois que cela commence par (une ancienne version de) jQuery. Vous devez faire référence à cela à partir du CDN Google, non seulement pour réduire le temps de chargement , mais potentiellement éviter une requête HTTP pour celui-ci .

Plus précisément, les bibliothèques d'interface utilisateur jQuery et jQuery les plus récentes peuvent être référencées à ces URL (voir cet article si vous êtes intéressé par la raison pour laquelle j'ai omis le http:):

//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js

//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js

Si vous utilisez l'un des thèmes d'interface utilisateur jQuery par défaut, vous pouvez également extraire son CSS et ses images du CDN Google .

Avec l'hébergement jQuery optimisé, vous devez également combiner awmlib2.jset tooltiplib.jsen un seul fichier.

Si vous résolvez ces problèmes, vous devriez constater une amélioration significative.


1
Excellent commentaire Dave! l'ancien 1.3 JQuery était beaucoup plus petit, alors j'ai pensé que pendant son fonctionnement, il pourrait être plus rapide. Mais j'aime vos recommandations: Lequel des liens Google CDN me suggérez-vous d'utiliser comme Jqyuery? Puis-je utiliser javascript JQ UI de la même manière? +1 merci beaucoup
Sam

2
Je recommande vivement d'utiliser la dernière version de jQuery (1.4.4 actuellement). Lorsqu'ils sont minifiés et gzippés, il n'y a que quelques octets de différence entre eux. J'ai mis à jour la réponse avec quelques liens vers les dernières versions de l'interface utilisateur jQuery et jQuery sur le CDN Google, que je recommanderais d'utiliser.
Dave Ward

1
Bonne astuce avec le sprite, qui devrait réduire le nombre de connexions ouvertes au serveur
JamesHalsall

travaille actuellement sur la réduction des connexions ouvertes (passe de 40 orso à maintenant 30 orso ... la poussée finale est la plus difficile car certaines des images répètent des arrière-plans et ne peuvent pas entrer dans un sprite (ou ???)
Sam

Mettre à jour la vitesse de la page: (96%) YSlow Grade: (90%) ... et les vignettes sont toujours aussi lentes que jamais!
Sam

17

J'ai eu un problème similaire il y a quelques jours et je l' ai trouvé head.js . C'est un plugin Javascript qui vous permet de charger tous les fichiers JS parallèlement. J'espère que cela pourra aider.


Incroyable! Comment ai-je pu oublier cela? +1 Je vais tester maintenant celui-ci. Ça sent comme une nuit fructueuse, merci Schattenbaum!
Sam

1
Puis-je vous demander si vous êtes le Schattenbaum de schattenbaum.net?
Pekka

12

Je suis loin d'être un expert mais ...

À ce propos: "Une demande conditionnelle If-Modified-Since a renvoyé le contenu complet inchangé." et mes commentaires.

Le code utilisé pour générer les vignettes doit vérifier les éléments suivants:

  1. Existe-t-il une version en cache de la vignette.
  2. La version mise en cache est-elle plus récente que l'image d'origine.

Si l'un de ces paramètres est faux, la vignette doit être générée et renvoyée quoi qu'il arrive. S'ils sont tous les deux vrais, la vérification suivante doit être effectuée:

  1. Existe-t-il un en-tête HTTP_IF_MODIFIED_SINCE
  2. L'heure de dernière modification de la version mise en cache est-elle la même que HTTP_IF_MODIFIED_SINCE

Si l'un de ces paramètres est faux, la vignette mise en cache doit être renvoyée.

Si les deux sont vrais, un état HTTP 304 doit être renvoyé. Je ne sais pas si c'est nécessaire, mais je renvoie également personnellement les en-têtes Cache-Control, Expires et Last-Modified avec le 304.

En ce qui concerne GZipping, j'ai été informé qu'il n'est pas nécessaire d'utiliser des images GZip, alors ignorez cette partie de mon commentaire.

Edit: Je n'ai pas remarqué votre ajout à votre message.

session_cache_limiter('public');
header("Content-type: " . $this->_mime);
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 2419200) . " GMT");
// I'm sure Last-Modified should be a static value. not dynamic as you have it here.
header("Last-Modified: " . gmdate("D, d M Y H:i:s",time() - 404800000) . " GMT");

Je suis également sûr que votre code doit vérifier l'en-tête HTTP_IF_MODIFIED_SINCE et y réagir. Il suffit de définir ces en-têtes et votre fichier .htaccess ne fournira pas le résultat requis.

Je pense que vous avez besoin de quelque chose comme ça:

$date = 'D, d M Y H:i:s T'; // DATE_RFC850
$modified = filemtime($filename);
$expires = strtotime('1 year'); // 1 Year

header(sprintf('Cache-Control: %s, max-age=%s', 'public', $expires - time()));
header(sprintf('Expires: %s', date($date, $expires)));
header(sprintf('Last-Modified: %s', date($date, $modified)));
header(sprintf('Content-Type: %s', $mime));

if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
    if(strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) === $modified) {
        header('HTTP/1.1 304 Not Modified', true, 304);
        // Should have been an exit not a return. After sending the not modified http
        // code, the script should end and return no content.
        exit();
    }
}
// Render image data

James, vous avez cloué l'essence du problème après votre modification dans votre réponse! le If Modified Sinceproblème semble fonctionner maintenant! Pourtant, les longs en-têtes / temps d'attente pour les minuscules pouces ne sont pas encore résolus ...
Sam

@James PS REdbot.org indique que votre en-tête Expires est une valeur incorrecte. Je pense que ce doit être GMT et non CET?
Sam le

@Sam Désolé, mon serveur est au Royaume-Uni, il génère donc automatiquement les dates GMT. Utilisez simplement la fonction PHP gmdate à la place si date. Cela devrait produire une date GMT par rapport à l'heure de votre serveur.
James

1
@Sam, Votre temps d'attente est le temps d'exécution du script. Soit cela prend beaucoup de temps pour passer votre code au point d'envoyer vos en-têtes, soit vous ne quittez pas après avoir envoyé vos en-têtes.
James

@James, je vois ... Mais à part ce générateur de vignettes php, il y a beaucoup d'autres scripts de longueur égale qui font diverses autres choses (traductions, chargement de menu, etc.) le tout en une fraction de temps ... ILS ne semble pas du tout goulot d'étranglement ... est-ce que cela dirige le problème vers le générateur de vignettes php UNIQUEMENT?
Sam

6

Wow, il est difficile d'expliquer les choses en utilisant cette image .. Mais ici, certains essais:

  • les fichiers 33-36 se chargent aussi tard, car ils sont chargés dynamiquement dans le swf, et le swf (25) est d'abord chargé complètement avant de charger tout contenu supplémentaire
  • les fichiers 20 et 21 sont peut - être (je ne sais pas, parce que je ne connais pas votre code) des bibliothèques chargées par all.js (11), mais que 11 s'exécute, il attend toute la page (et les ressources) à charger (vous devriez changer cela en domready)
  • les fichiers 22-32 sont chargés par ces deux bibliothèques, encore une fois après leur chargement complet

Point intéressant. Je pense qu'il n'y a rien autour du swf ... Comment puis-je changer quoi en domready? J'ai une idée de ce que tu veux dire. Il s'agit du moment où le javascript est prêt et indique sur le document prêt ceci ou cela? ce document.ready doit-il être remplacé par dom.ready?
Sam le

@Sam si vous utilisez la mise en cache côté client (et vous devriez l'être), vous pouvez charger les ressources utilisées par le swf dans js ou des div cachés sur votre page afin que lorsque le swf les demande, elles soient déjà chez le client.
Endophage

4

Juste une simple supposition car ce type d'analyse nécessite beaucoup de tests A / B: votre domaine .ch semble être difficile à atteindre (longues bandes vertes avant l'arrivée du premier octet).

Cela signifierait que le site Web .ch est mal hébergé ou que votre FAI n'a pas un bon chemin vers eux.

Compte tenu des diagrammes, cela pourrait expliquer un gros impact sur les performances.

Sur une note latérale, il y a cet outil cool cuzillion qui pourrait vous aider à trier les choses en fonction de votre commande de chargement des ressources.


4

Essayez d'exécuter des tests Y! Slow et Page Speed ​​sur votre site / page, et suivez les instructions pour trier les éventuels goulots d'étranglement des performances. Vous devriez obtenir d'énormes gains de performances une fois que vous obtenez un score plus élevé en Y! Slow ou en Vitesse de page.

Ces tests vous diront ce qui ne va pas et ce qu'il faut changer.


Merci! les scores sont: 92 sur Page Speed ​​et 93 sur Ylow. Ce qui manque sont: KEEP ALIVE = désactivé et ne pas utiliser CDN.
Sam le

MISE À JOUR: 96 et 90 respectivement actuellement
Sam

4

Votre script PHP génère donc les vignettes à chaque chargement de page? Tout d'abord, si les images miniatures ne changent pas souvent, pourriez-vous configurer un cache de sorte qu'elles n'aient pas à être analysées à chaque chargement de la page? Deuxièmement, votre script PHP utilise-t-il quelque chose comme imagecopyresampled()pour créer les vignettes? C'est un sous-échantillon non trivial et le script PHP ne retournera rien tant qu'il n'aura pas fini de réduire les choses. Utiliser à la imagecopymerged()place réduira la qualité de l'image, mais accélérera le processus. Et quelle réduction faites-vous? Ces vignettes ont-elles 5% de la taille de l'image originale ou 50%? Une plus grande taille de l'image d'origine entraîne probablement un ralentissement puisque le script PHP doit obtenir l'image d'origine en mémoire avant de pouvoir la réduire et afficher une miniature plus petite.


Merci MidnightLightning! Il y a un dossier de cache où les JPG miniatures sont créés et réutilisés à partir de, bien que j'ai le sentiment qu'il y a ici le problème du script que j'ai acheté (et semble fonctionner bien pour les autres)
Sam

2
Si les miniatures sont mises en cache, assurez-vous que le script qui les extrait du cache utilise readfile()plutôt que file_get_contents()suivi d'un écho, qui attend de sortir quoi que ce soit jusqu'à ce que tout le fichier soit déplacé dans la mémoire du script PHP.
MidnightLightning le

Mieux encore - si les fichiers sont mis en cache, générez le HTML d'une manière qui extrait directement l'image mise en cache du disque sans passer par PHP. C'est ce que je fais dans mes scripts pour videodb.net
andig

"Il y a un dossier de cache où ..." et à quelle vitesse sont-ils déréférencés? Votre URL pointe-t-elle directement vers un fichier mis en cache ou un script PHP? Redirigez-vous ou utilisez-vous readfile ()? Le même script PHP contient-il le code de génération de vignettes - ou reportez-vous le chargement de la majeure partie du code en utilisant include / erquire?
symcbean

4

J'ai trouvé l'URL de votre site Web et vérifié un fichier jpg individuel sur la page d'accueil. Alors que le temps de chargement est maintenant raisonnable (161 ms), il attend 126 ms, ce qui est beaucoup trop.

Vos derniers en-têtes modifiés sont tous définis sur Sam, 01 Jan 2011 12:00:00 GMT, ce qui semble trop "rond" pour être la date réelle de génération ;-)

Etant donné que Cache-control est "public, max-age = 14515200", les en-têtes arbitraires de dernière modification peuvent poser problème après 168 jours.

Quoi qu'il en soit, ce n'est pas la vraie raison des retards.

Vous devez vérifier ce que fait votre générateur de vignettes lorsque la vignette existe déjà et ce qui pourrait prendre autant de temps à vérifier et à livrer l'image.

Vous pouvez installer xdebug pour profiler le script et voir où se trouvent les goulots d'étranglement.

Peut-être que le tout utilise un framework ou se connecte à une base de données pour rien. J'ai vu mysql_connect () très lent sur certains serveurs, principalement parce qu'ils se connectaient en utilisant TCP et non socket, parfois avec des problèmes DNS.

Je comprends que vous ne pouvez pas publier votre générateur payant ici mais j'ai peur qu'il y ait trop de problèmes possibles ...


Merci pour votre détective et spot sur les indices Capsule! Tout d'abord: il n'y a pas de base de données. Vos conclusions sont les mêmes que les miennes: son attente 90% du temps? Petits pouces fous. Réflexions intéressantes sur les derniers en-têtes modifiés, car selon James post ici, je devais définir ces en-têtes de dernière modification sur une heure STATIC (fixe), pas une heure dynamique / toujours changeante définie par les générateurs php gmdate. Ou peut-être voulez-vous dire autre chose ici? (Nominé pour la prime)
Sam

1
Pour être parfait, il doit refléter la date de génération réelle, par exemple en obtenant le filemtime () de la vignette mise en cache. Ce qui serait intéressant à tester, c'est d'accéder à un fichier PHP vide, ou à un fichier PHP faisant juste écho à "test" et de voir combien vous attendez sur celui-ci. Peut-être que tout le serveur est lent et a un impact sur chaque script PHP, quoi qu'il fasse.
Capsule

1
Je constate également un délai relativement long sur les fichiers statiques purs (par exemple les images liées aux pouces), comme 36ms. Sur l'un des serveurs que j'administre (qui n'est pas une bête ... dual core avec 2 Go de RAL), j'obtiens presque la moitié, comme 20 ms sur des fichiers statiques.
Capsule du

Intéressant ... 1. quel logiciel / outil en ligne utilisez-vous pour mesurer? 2. Vos mesures plus rapides de 20 ms sont-elles cohérentes (combien de ± xx%) trouvez-vous que vos résultats varient? Dans mon cas, cela varie vraiment beaucoup en fonction de l'outil de test que j'utilise. certains sont très cohérents ( gtmetrix.com ) certains sont vraiment variables ( pingdom.com ) et il est difficile de donner des temps en XX ms car ils changent à chaque fois ...
Sam

J'utilise l'onglet NET de Firebug. 20 ms est le timing le plus rapide que j'obtiens. Cela varie entre 20 et 28. Bien sûr, les 36 ms que j'ai mesurés sur votre serveur étaient aussi les plus rapides.
Capsule du

4

S'il n'y a pas vraiment de bonne raison (ce n'est généralement pas le cas), vos images ne doivent pas appeler l'interpréteur PHP.

Créez une règle de réécriture pour votre serveur Web qui serveur l'image directement si elle se trouve sur le système de fichiers. Si ce n'est pas le cas, redirigez vers votre script PHP pour générer l'image. Lorsque vous modifiez l'image, modifiez le nom de fichier des images pour forcer les utilisateurs disposant d'une version mise en cache à récupérer l'image nouvellement modifiée.

Si cela ne fonctionne pas au moins, vous le ferez maintenant, cela n'a rien à voir avec la façon dont les images sont créées et vérifiées.


Merci Goran, mais ce n'est pas la solution élégante que je souhaite: je pense qu'il y a quelque chose de louche dans mon cas, et que normalement il ne faut vraiment pas autant de temps à un script php pour savoir s'il faut passer un en-tête 304 ou cuire le image etc. merci de toute façon pour votre suggestion car elle oriente le problème dans une perspective entièrement nouvelle! Ce qui est précieux en soi +1
Sam

3

Étudiez l'utilisation des données de session par PHP. Peut-être (juste peut-être) que le script PHP de génération d'images attend d'obtenir un verrou sur les données de session, qui sont verrouillées par la page principale de rendu d'image fixe ou d'autres scripts de rendu d'image. Cela rendrait toutes les optimisations JavaScript / navigateur presque inutiles, car le navigateur attend le serveur.

PHP verrouille les données de session pour chaque script en cours d'exécution, à partir du moment où la gestion de session commence, jusqu'à la fin du script, ou lorsque session_write_close () est appelée. Cela sérialise efficacement les choses. Consultez la page PHP sur les sessions, en particulier les commentaires, comme celui-ci .


Merci pour la suggestion Ricardo! Il semble qu'Alix suggère la même chose que vous (non?). Concrètement, que me proposez-vous de mettre / supprimer du code, puis de tester à nouveau les graphiques puis de rendre compte? Très appréciée.
Sam

1
Oui je le pense. Je vous suggère de changer les scripts de génération d'images afin qu'ils ne dépendent pas des données $ _SESSION ou similaires (peut-être qu'ils ne le font pas déjà). Ensuite, utilisez session_write_close () dès que possible , ou, mieux encore, évitez d'utiliser des sessions sur ces scripts. Découvrez php.net/manual/en/function.session-write-close.php
Ricardo Pardini

3

C'est juste une supposition sauvage puisque je n'ai pas regardé votre code mais je soupçonne que les sessions peuvent jouer un rôle ici, ce qui suit est de l'entrée du manuel PHP sur session_write_close():

Les données de session sont généralement stockées après la fin de votre script sans qu'il soit nécessaire d'appeler session_write_close (), mais comme les données de session sont verrouillées pour empêcher les écritures simultanées, un seul script peut fonctionner sur une session à tout moment. Lorsque vous utilisez des jeux de cadres avec des sessions, vous verrez les cadres se charger un par un en raison de ce verrouillage. Vous pouvez réduire le temps nécessaire pour charger toutes les trames en mettant fin à la session dès que toutes les modifications apportées aux variables de session sont effectuées.

Comme je l'ai dit, je ne sais pas ce que fait votre code, mais ces graphiques semblent étrangement suspects. J'ai eu un problème similaire lorsque j'ai codé une fonction de service de fichiers en plusieurs parties et j'ai eu le même problème. Lors de la diffusion d'un fichier volumineux, je ne pouvais pas faire fonctionner la fonctionnalité multi-parties ni ouvrir une autre page tant que le téléchargement n'était pas terminé. L'appel a session_write_close()résolu mes deux problèmes.


Merci Alix pour votre suggestion. Une question: la exit();fonction est-elle dans les mêmes lignes que le session_write_close();? actuellement, l'auteur original du code étudie le problème, mais il semble qu'il soit également un peu dans le noir, car la mise à jour généreuse du code avec une meilleure gestion If-Modified-Since semble avoir les mêmes retards (nouvelle cascade les graphiques ont produit les mêmes graphiques, bien que les résultats réels aient semblé / senti des chargements plus rapides! C'est un problème très étrange ...
Sam

1
@Sam: Je ne peux pas vous donner de sources pour le moment, mais je crois que exit () appelle d'abord tous les destructeurs et / ou fonctions enregistrés pour l'arrêt et alors seulement la session est fermée. Quoi qu'il en soit, je parie que votre problème se situe probablement avant votre appel exit (). Voir aussi: stackoverflow.com/questions/1674314/…
Alix Axel

2

Avez-vous essayé de remplacer les vignettes générées par php par des images régulières pour voir s'il y a une différence? Le problème pourrait être autour - un bug dans votre code php conduisant à une régénération de la vignette à chaque invocation du serveur - un retard dans votre code (sleep ()?) Associé à un problème d'horloge - un problème hardrive provoquant une très mauvaise condition de concurrence puisque toutes les vignettes sont chargées / générées en même temps.


Quelque chose que j'ai pensé à un moment donné en essayant +1 pour lire mes pensées et révéler la première solution que j'ai déjà faite. Ce que j'espérais, c'était de trouver que les images normales se chargeraient également lentement de sorte que cela pourrait être la vitesse de téléchargement de la bande passante ou quelque chose de physiquement limitant, mais j'ai trouvé à la place que les images de vidage statiques normales (j'ai enregistré les pouces générés et téléchargés comme statiques) celles-ci chargées Extrêmement vite. Donc ça doit faire avec ce que le générateur de vignettes php!
Sam

2

Je pense qu'au lieu d'utiliser ce script de générateur de vignettes, vous devez essayer TinySRC pour une génération de vignettes rapide et hébergée dans le cloud. Il a une API très simple et facile à utiliser, vous pouvez utiliser comme: -

http://i.tinysrc.mobi/ [hauteur] / [largeur] /http://domain.tld/path_to_img.jpg

[largeur] (facultatif): - Il s'agit d'une largeur en pixels (qui remplace le dimensionnement adaptatif ou familial). S'il est préfixé par «-» ou «x», il soustrayera ou diminuera à un pourcentage de la taille déterminée.

[hauteur] (facultatif): - Il s'agit d'une hauteur en pixels, si la largeur est également présente. Il remplace également le dimensionnement adaptatif ou familial et peut être préfixé par «-» ou «x».

Vous pouvez consulter le résumé de l'API ici


FAQ

Combien me coûte tinySrc?

Rien.

Quand puis-je commencer à utiliser tinySrc?

Maintenant.

Quelle est la fiabilité du service?

Nous ne donnons aucune garantie sur le service tinySrc. Cependant, il fonctionne sur une infrastructure cloud distribuée majeure , de sorte qu'il offre une haute disponibilité dans le monde entier. Cela devrait suffire à tous vos besoins.

À quelle vitesse est-ce?

tinySrc met en cache les images redimensionnées en mémoire et dans notre banque de données pendant jusqu'à 24 heures , et il ne récupérera pas votre image d'origine à chaque fois. Cela rend les services extrêmement rapides du point de vue de l'utilisateur. (Et réduit la charge de votre serveur comme un bel effet secondaire.)


Bonne chance. Juste une suggestion, puisque tu ne nous montre pas le code: p


2

Comme certains navigateurs ne téléchargent que 2 téléchargements parallèles par domaine, vous ne pourriez pas ajouter de domaines supplémentaires pour partager les demandes sur deux à trois noms d'hôte différents. par exemple 1.imagecdn.com 2.imagecdn.com


+1 pour votre suggestion: merci, mais si vous regardez de plus près mes (admis: dessins très chaotiques) vous verrez que certains éléments viennent de ....... es certains viennent de ........ com .......... de MAIS, cela ne fonctionne peut-être pas aussi bien que votre suggestion? (Je vois que vous suggérez des sous-domaines, au lieu de simplement des domaines différents.)
Sam

1

Tout d'abord, vous devez gérer les If-Modified-Sincedemandes de manière appropriée, comme l'a dit James. Cette erreur indique que: "Quand je demande à votre serveur si cette image a été modifiée depuis la dernière fois, il envoie l'image entière au lieu d'un simple oui / non".

Le temps entre la connexion et le premier octet est généralement le temps que prend votre script PHP pour s'exécuter. Il est évident que quelque chose se passe lorsque ce script commence à s'exécuter.

  1. Avez-vous envisagé de le profiler? Cela peut avoir des problèmes.
  2. Combiné avec le problème ci-dessus, votre script peut s'exécuter beaucoup plus de fois que nécessaire. Idéalement, il ne devrait générer des vignettes que si l'image d'origine est modifiée et envoyer des vignettes en cache pour chaque autre demande. Avez-vous vérifié que le script génère les images inutilement (par exemple pour chaque requête)?

Générer des en-têtes appropriés via l'application est un peu délicat, de plus ils peuvent être écrasés par le serveur. Et vous êtes exposé à des abus car toute personne qui envoie des en-têtes de demande sans cache entraînera le fonctionnement continu de votre générateur de vignettes (et augmentera les charges). Donc, si possible, essayez d'enregistrer ces vignettes générées, appelez les images enregistrées directement à partir de vos pages et gérez les en-têtes depuis .htaccess. Dans ce cas, vous n'auriez même pas besoin de quoi que ce soit dans votre .htaccesssi votre serveur est correctement configuré.

En dehors de ceux-ci, vous pouvez appliquer certaines des idées d'optimisation brillantes des parties de performance de cette belle question globale sur la façon de faire des sites Web de la bonne manière , comme diviser vos ressources en sous-domaines sans cookie, etc. Mais en tout cas, une image 3k ne devrait pas prendre une seconde à charger, cela est apparent par rapport aux autres éléments des graphiques. Vous devriez essayer de repérer le problème avant d'optimiser.


-1: Répondre à une demande conditionnelle avec `` Non modifié '' et sans délai d'expiration révisé ralentira votre site dans 99,9% des cas (BTW, AFAIK, il n'y a aucun moyen pour qu'Apache émette des informations de mise en cache révisées avec une réponse 304)
symcbean

Et qu'est-ce que cela a à voir avec ma réponse?
Halil Özgür

1

Avez-vous essayé de configurer plusieurs sous-domaines sous le serveur Web NGINX spécialement pour servir des données statiques telles que des images et des feuilles de style? Quelque chose d'utile peut déjà être trouvé dans cette rubrique .


Merci! Après quelques recherches, il semble cependant que la mise en place de sous-domaines pour serveur des cookies statiques ne fait qu'un site plus rapide, lorsqu'il y a beaucoup d'images, au prix d'un peu plus de frais généraux. Dans mon cas, je parie que les 6 images ne se chargeront pas plus rapidement que la surcharge du sous-domaine / extra. Droite?
Sam

1
NGinx prend en charge sendfile syscall, qui peut envoyer des fichiers directement à partir du disque dur. veuillez consulter le document suivant wiki.nginx.org/HttpCoreModule sur les directives 'sendfile', 'aio'. Ce serveur Web sert des fichiers statiques comme des images beaucoup plus rapidement qu'apache.
nefo_x

intéressant ... Je ne savais pas qu'il pouvait y avoir quelque chose de mieux qu'Apache. Au fait, qu'entendez-vous par straight from hdd. voulez-vous dire à la place straight from DDR3 RAM/ straight from Solid State DiskJe sais que les disques durs, contrairement aux disques RAM DDR3 ou Solid State, ont un temps d'accès très lent. Mais je pense que ce n'est pas le goulot d'étranglement ici ...
Sam

1
le fait est que nginx ne met pas en mémoire tampon la sortie de données statiques, comme le fait Apache.
nefo_x

1

En ce qui concerne les vignettes retardées, essayez de mettre un appel à flush () immédiatement après le dernier appel à header () dans votre script de génération de vignettes. Une fois cela fait, régénérez votre graphique en cascade et voyez si le retard est maintenant sur le corps au lieu des en-têtes. Si tel est le cas, vous devez examiner longuement la logique qui génère et / ou produit les données d'image.

Le script qui gère les vignettes devrait, espérons-le, utiliser une sorte de mise en cache afin que toutes les actions qu'il entreprenne sur les images que vous diffusez ne se produisent que lorsque cela est absolument nécessaire. Il semble qu'une opération coûteuse ait lieu chaque fois que vous diffusez les vignettes, ce qui retarde toute sortie (y compris les en-têtes) du script.


+1 Une supposition excitante va l'essayer maintenant! fera rapport quand j'aurai la nouvelle cascade qui coule ...
Sam

Malheureusement, après avoir ajouté flush();juste après les en-têtes, il ne semble y avoir aucun changement! Qu'est-ce que cela pouvait signifier?
Sam

Pas certain. Existe-t-il un moyen de nous lier au script PHP en question? Je sais que vous avez payé pour cela, mais il est incroyablement difficile de dire ce qui pourrait causer le comportement sans pouvoir voir ce qu'il fait.
AR Younce

Les vignettes sont-elles référencées dans CSS ou dans les balises <img>?
AR Younce

Qu'entendez-vous par référencé en css? ils sont à côté du corps html et comme suit: <img src="thumbprocessor.php?src=/folder/image.jpg&w=100&h=200" id="thumbnail"/>
Sam

1

La majorité du problème de lenteur est que votre TTFB (Time to first byte) est trop élevé. C'est une question difficile à aborder sans devenir intime avec les fichiers de configuration de votre serveur, le code et le matériel sous-jacent, mais je peux voir que c'est endémique à chaque demande. Vous avez trop de barres vertes (mauvaise) et très peu de barres bleues (bonne). Vous voudrez peut-être arrêter d'optimiser le frontend pendant un moment, car je pense que vous avez fait beaucoup dans ce domaine. Malgré l'adage selon lequel " 80 à 90% du temps de réponse de l'utilisateur final est passé sur le frontend ", je pense que le vôtre se produit dans le backend.

TTFB est un élément de backend, un élément de serveur, un prétraitement avant la sortie et une négociation.

Chronométrez l'exécution de votre code pour trouver des éléments lents comme les requêtes de base de données lentes, le temps d'entrée et de sortie des fonctions / méthodes pour trouver des fonctions lentes. Si vous utilisez php, essayez Firephp . Parfois, il s'agit d'une ou deux requêtes lentes exécutées au démarrage ou à l'initialisation, comme l'extraction des informations de session ou la vérification de l'authentification, etc. L'optimisation des requêtes peut conduire à de bons gains de performances. Parfois, le code est exécuté en utilisant php prepend ou spl autoload afin qu'ils fonctionnent sur tout. D'autres fois, cela peut être une configuration apache mal configurée et des ajustements qui sauvent la mise.

Recherchez les boucles inefficaces. Recherchez les appels de récupération lents des caches ou les opérations d'E / S lentes causées par des lecteurs de disque défectueux ou une utilisation élevée de l'espace disque. Recherchez les utilisations de la mémoire, ce qui est utilisé et où. Exécutez un test Webpagetest répété de 10 exécutions sur une seule image ou un seul fichier en utilisant uniquement la première vue à partir de différents endroits dans le monde et non au même endroit. Et lisez vos journaux d'accès et d'erreurs, trop de développeurs les ignorent et ne se fient qu'aux erreurs affichées à l'écran. Si votre hébergeur a du soutien, demandez-lui de l'aide, s'il ne lui demande peut-être pas poliment de l'aide de toute façon, cela ne fera pas de mal.

Vous pouvez essayer DNS Prefetching pour lutter contre les nombreux domaines et ressources, http://html5boilerplate.com/docs/DNS-Prefetching/

Le serveur est-il le vôtre un bon / décent serveur? Parfois, un meilleur serveur peut résoudre de nombreux problèmes. Je suis un fan de la mentalité «le matériel est bon marché, les programmeurs sont chers », si vous avez la chance et l'argent de mettre à niveau un serveur. Et / Ou utilisez un CDN comme maxcdn ou cloudflare ou similaire.

Bonne chance!

(ps, je ne travaille pour aucune de ces entreprises. De plus, le lien cloudflare ci-dessus soutiendra que TTFB n'est pas si important que cela, je l'ai ajouté pour que vous puissiez en avoir une autre.)


Cher Anthony, merci beaucoup pour cette connaissance «de fond» perspicace. Je conviens que parfois le matériel est le goulot d'étranglement et que c'est moins évident à mesurer, surtout lorsque la société d'hébergement héberge la partie serveur dans un environnement d'hébergement partagé. Je pense que cloudflare est une bonne option à essayer en combinaison avec l'optimisation de la configuration Apache. Salutations!
Sam

-1

Désolé de dire, vous fournissez à peu de données. Et vous aviez déjà de bonnes suggestions.

Comment servez-vous ces images? Si vous les diffusez via PHP, vous faites une très mauvaise chose, même si elles sont déjà générées.

NE JAMAIS DIFFÉRER D'IMAGES AVEC PHP. Cela ralentira votre serveur, quelle que soit la façon dont vous l'utilisez.

Mettez-les dans un dossier accessible, avec un URI significatif. Appelez-les ensuite directement avec leur véritable URI. Si vous avez besoin d'une génération à la volée, vous devez mettre un .htaccess dans le répertoire images qui redirige vers un générateur php-script uniquement si l'image de la requête est manquante. (c'est ce qu'on appelle la stratégie de cache à la demande).

Faire cela corrigera la session php, le proxy du navigateur, la mise en cache, ETAGS, tout à la fois.

WP-Supercache utilise cette stratégie, si elle est correctement configurée.

J'ai écrit ceci il y a quelque temps ( http://code.google.com/p/cache-on-request/source/detail?r=8 ), les dernières révisions sont cassées, mais je suppose que 8 ou moins devraient fonctionner et vous pouvez prenez le .htaccess comme exemple juste pour tester les choses (bien qu'il existe de meilleures façons de configurer le .htaccess que la façon dont je le faisais auparavant).

J'ai décrit cette stratégie dans ce billet de blog ( http://www.stefanoforenza.com/need-for-cache/ ). Il est probablement mal écrit mais cela peut aider à clarifier les choses.

Lectures complémentaires: http://meta.wikimedia.org/wiki/404_handler_caching


Attention, ErrorDocument n'est pas vraiment la meilleure chose que vous puissiez faire, car il a généré des entrées dans le journal des erreurs d'Apache, une redirection -f serait meilleure.
tacone

Merci pour votre entrée tacone. Êtes-vous en train de dire que, quelle que soit la qualité du script php, il ralentira le serveur ou, comme vous l'avez dit dans votre message, "Il tuera votre serveur, quoi qu'il arrive."
Sam

cela ralentira le serveur, quelle que soit la qualité du script. Pour chaque image, le serveur devra charger php et lui faire diffuser l'image octet par octet. Laissez apache faire le travail sans même passer par l'interpréteur php. En conséquence, de nombreuses autres erreurs possibles seront automatiquement évitées, telles que les sessions, la longueur du contenu, la mise en cache, mime / type, etc.
tacone

Vote downers, pouvez-vous expliquer pourquoi?
tacone
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.