8791 sujets

Développement web côté serveur, CMS

Pages :
Bonjour à tous,

Je viens de faire une folie, j'ai un hébergeur (PlanetHoster), au-revoir Free.fr. Seulement, même si j'ai un nom de domaine, ben Free me manque car c'était plus rapide chez eux..

Pouvez-vous me confirmer que le temps d'affichage de mon petit forum est anormalement long ? Sachez que ce forum s'affichait environ 2 fois plus vite sous Free. Pourquoi c'est donc si lent ? Qu'est-ce qui pourrait provoquer ces choses-là ? Y a-t-il des choses à configurer sur le serveur ?

A noter que l'ensemble des pages, qu'il y ait des requêtes sql ou pas, s'affiche de 2 à 4 fois plus lentement que chez Free. Pourtant je croyais que Free n'était pas connu pour la rapidité de ses serveurs gratuits.

Merci pour vos réponses. En fait je suis sur une période d'essai de 1 mois, et en l'état il n'y a que le nom de domaine qui me convainc..

Voici le site et la page en question : http://www.pronostics-formule1.fr/discussion.php
Administrateur
Bonjour,

il est fortement conseillé de ne pas lier nom de domaine et hébergeur, c'est-à-dire qu'il y ait la possibilité d'avoir un nom de domaine chez un registrar et l'hébergement chez un hébergeur qui ne soit pas ce même registrar. Je ne connais pas le registrar-hébergeur cité mais c'est à vérifier (précision : je ne dis pas qu'il faut séparer les deux style Gandi+OVH, ça peut être OVH pour les deux mais lui sépare bien les deux et permet de faire pointer le NDD vers l'extérieur enfin je crois et de confier la gestion DNS du NDD à n'importe qui d'autre)

Hébergement : c'est une offre sur serveur mutualisé je suppose ? Il faut partager un gros serveur entre beaucoup d'autres sites, le serveur MySQL peut causer le ralentissement car lui aussi est partagé (c'était et c'est peut-être encore le problème chez Free m'enfin c'est gartuit hein ...). Chaque hébergeur fixe le nombre de sites, fait ou non la police à ceux qui abusent des ressources, etc
D'un autre côté tu écris "configurer le serveur". À quoi aurais-tu accès ?

Temps d'affichage : c'est pas rapide mais c'est pas non plus rédhibitoire. Par contre la page est chargée via Javascript avec un effet d'apparition : c'est une perte de temps pour le visiteur. Ah ben sans Javascript RIEN ne s'affiche en fait. Sérieusement ? Smiley sweatdrop

Tu as créé ton sujet à 17h44. Ici aussi ça rame (ou ramait) à cette heure-ci, c'est la grosse affluence pour les français/belges/suisses pour perdre 10 minutes au boulot avant de rentrer ou bien en arrivant chez soi. Smiley lol
Essaie à 3H30 du mat' pour comparer (pas à l'heure pile en pleine nuit, des scripts de maintenance peuvent être programmés à ces instants-là et durer quelques minutes) ou avant 8H30
Felipe a écrit :
il est fortement conseillé de ne pas lier nom de domaine et hébergeur, c'est-à-dire qu'il y ait la possibilité d'avoir un nom de domaine chez un registrar et l'hébergement chez un hébergeur qui ne soit pas ce même registrar. Je ne connais pas le registrar-hébergeur cité mais c'est à vérifier (précision : je ne dis pas qu'il faut séparer les deux style Gandi+OVH, ça peut être OVH pour les deux mais lui sépare bien les deux et permet de faire pointer le NDD vers l'extérieur enfin je crois et de confier la gestion DNS du NDD à n'importe qui d'autre)


J'ai relu plusieurs fois ton post, mais je comprends pas ce que tu veux dire. Smiley confused

Felipe a écrit :
Hébergement : c'est une offre sur serveur mutualisé je suppose ? Il faut partager un gros serveur entre beaucoup d'autres sites, le serveur MySQL peut causer le ralentissement car lui aussi est partagé (c'était et c'est peut-être encore le problème chez Free m'enfin c'est gartuit hein ...). Chaque hébergeur fixe le nombre de sites, fait ou non la police à ceux qui abusent des ressources, etc


Oui c'est une offre mutualisée. Quelque soit l'heure, la vélocité est la même. C'est un point. Là où je tique, c'est que c'est 2 à 4 fois moins rapide que Free.fr.. Smiley sweatdrop PS : PlanetHoster se trouve au Canada.

Felipe a écrit :
D'un autre côté tu écris "configurer le serveur". À quoi aurais-tu accès ?


Aucune idée, c'est la première fois que je suis sur ce genre de serveurs qui par exemple ouvrent plus de possibilités concernant les htaccess, la compression, le cache, etc..

Felipe a écrit :
Par contre la page est chargée via Javascript avec un effet d'apparition : c'est une perte de temps pour le visiteur. Ah ben sans Javascript RIEN ne s'affiche en fait. Sérieusement ? Smiley sweatdrop


Shame on me, c'est un parti pris. Pour quelles raisons ? Esthétiques avant tout. Puis après tout je me dis que l'immense majorité des gens ont javascript activé. Et puis quoiqu'il en soit j'ai un module de pronostics dynamique grâce à javascript, et celui qui ne peut pas l'utiliser ne peut pas jouer.. Alors voilou.

Felipe a écrit :
Tu as créé ton sujet à 17h44. Ici aussi ça rame (ou ramait) à cette heure-ci, c'est la grosse affluence pour les français/belges/suisses pour perdre 10 minutes au boulot avant de rentrer ou bien en arrivant chez soi. Smiley lol


Justement, je trouve que la réaction de votre site est extra. Pas de délai, la réactivité est impressionnante alors que vous avez je ne sais combien de contenu à charger.

Felipe a écrit :
salut

20h53, aussi rapide qu'une formule 1 smile 1.3s pour affichage complet, très honorable donc.


Smiley biggol Comment c'est y possible ? Chez moi ça rame sous FF3.6 (pas sous chrome), et Firebug m'indique clairement que chez Free c'est bien plus véloce..

Pouvez-vous m'expliquer : Firebug m'indique 211ms (onload: 4.34s). Ca signifie quoi la première valeur ? M'enfin voilà, 4 à 5 secondes pour charger une page, je trouve ça vraiment lent Smiley ohwell
Modifié par Bertrand40 (16 Feb 2011 - 21:18)
Modérateur
Bertrand40 a écrit :

J'ai relu plusieurs fois ton post, mais je comprends pas ce que tu veux dire. Smiley confused


Grosso modo, tu peux acheter ton nom de domaine chez Monsieur X, et faire héberger ton site chez Madame Y. Suffit ensuite de configurer ton nom de domaine pour qu'il pointe chez Madame Y.

Le nom de domaine et l'hébergement sont deux choses complètement indépendantes.
Tony Monast a écrit :


Grosso modo, tu peux acheter ton nom de domaine chez Monsieur X, et faire héberger ton site chez Madame Y. Suffit ensuite de configurer ton nom de domaine pour qu'il pointe chez Madame Y.

Le nom de domaine et l'hébergement sont deux choses complètement indépendantes.


D'accord. La hotline de l'hébergeur a déjà passé quelques heures à tenter de m'aider. Je pense qu'ils ont fait cette démarche dont tu parles, non ?

Comment expliques-tu que chez Free ça soit (beaucoup) plus rapide ?

Sinon concernant Javascript c'est décidé. Je vais au-moins débrider une partie du site.

Bonne journée.
Deux explications probables:
- l'Ip de ton site indique qu'il est au Canada. Comme tu fais pas mal de requêtes (46 sur la page d'accueil), chaque aller retour traverse l'Atlantique
-la charge des serveurs de free était peut tout simplement inférieure.

Par ailleurs, tu peux améliorer tes perfs en réduisant le nombre de requêtes. Rend le css statique, il est visiblement généré dynamiquement et nécessite presque une demi seconde d'attente (contre 5 fois moins sur Alsacréations par exemple, sans compter l'aller retour requête réponse).
Vu le nombre important d'images, ça peut valoir le coup de les héberger dans des sous domaines ou dans le cloud (aws S3), pour paralléliser les chargements.

Si tu es encore motivé, tu peux encore gratter quelques ms :
Configure tes etags et les expires header
paolo : le truc de l'IP, c'est pas sensé être quelque chose de non-absolu, genre tu peux faire 2 fois le tour de la planète pour arriver sur un site dans le même pays, à cause des requêtes DNS, justement ?

Sinon, les CSS et autres médias externes, oui, les conseils généraux d'alsacreations sont à prendre évidemment en compte.

Mais chez moi, le calcul de la page (donc dynamique coté serveur) est assez long. Si tu as un changement significatif entre free et ce nouvel hébergeur, vérifies coté des logs voire même des stats si tu as un module pour. La charge peut être un algo PHP mal optimisé sur des versions plus récentes de PHP (ça peut arriver) ou des requêtes SQL foireuses (plus probables) qui ne se voyaient pas sur un serveur Free.
Bertrand40 a écrit :

Shame on me, c'est un parti pris. Pour quelles raisons ? Esthétiques avant tout. Puis après tout je me dis que l'immense majorité des gens ont javascript activé. Et puis quoiqu'il en soit j'ai un module de pronostics dynamique grâce à javascript, et celui qui ne peut pas l'utiliser ne peut pas jouer.. Alors voilou.


Quelle hérésie !!!
Tu as pensé au référencement, l'accessibilité…
Re, désolé j'étais pas dispo pour répondre hier.

paolo a écrit :
Par ailleurs, tu peux améliorer tes perfs en réduisant le nombre de requêtes. Rend le css statique, il est visiblement généré dynamiquement et nécessite presque une demi seconde d'attente (contre 5 fois moins sur Alsacréations par exemple, sans compter l'aller retour requête réponse).
Vu le nombre important d'images, ça peut valoir le coup de les héberger dans des sous domaines ou dans le cloud (aws S3), pour paralléliser les chargements.

Si tu es encore motivé, tu peux encore gratter quelques ms :
Configure tes etags et les expires header


Ouch.. ça fait déjà beaucoup de choses à faire, que je ne maîtrise pas.

1- Que veux-tu dire par CSS statique ?
2- Ok, les Etags et les expire headers, je crois que contrairement à Free, il m'est possible de les régler en .htaccess

Lpu8er a écrit :
Mais chez moi, le calcul de la page (donc dynamique coté serveur) est assez long. Si tu as un changement significatif entre free et ce nouvel hébergeur, vérifies coté des logs voire même des stats si tu as un module pour. La charge peut être un algo PHP mal optimisé sur des versions plus récentes de PHP (ça peut arriver) ou des requêtes SQL foireuses (plus probables) qui ne se voyaient pas sur un serveur Free.


Ben je me demande si c'est pas simplement ça avant tout. Dis-moi stp si tu es d'accord avec mon raisonnement :
1- Car si ma base de données ridiculement petite (900 messages dans la discussion, c'est tout), n'est pas capable de me recracher son contenu en moins de 5 secondes, c'est qu'il y a un soucis non ?
2- D'autant que dans ma requête je limite le nombre de sujets à afficher (15), et qu'il n'y a quasiment aucune image
3- Lorsqu'on entre dans un sujet (page messages d'un sujet), la page s'affiche bien plus vite.... alors qu'il y a beaucoup plus de requêtes a priori

Par hasard, est-ce que cette requête te fait sauter au plafond ? (c'est la requête principale qui liste les messages)


$sql = mysql_query('
SELECT * 
FROM discussion 
WHERE id IN 
(SELECT MAX(id) FROM discussion GROUP BY sujet HAVING epingle = 0) 
ORDER BY id DESC 
LIMIT ' . intval($premierMessage) . ', ' . intval($nombreMsgPage) . '');


bilhackmac a écrit :
Quelle hérésie !!!
Tu as pensé au référencement, l'accessibilité…


Oui, j'y ai songé en effet. C'est un parti pris, car à la base nous étions simplement quelques membres de la famille et connaissant l'échantillon, j'avais ni besoin d'accessibilité ni de référencement. Mais là en effet c'est peut-être en train de changer. Raison pour laquelle vous m'avez décidé : il y aura des noscripts partout ^^

Merci encore pour ces précieuses aides. Je vous tiens au courant du bon ou mauvais avancement des choses..

@+
Bertrand40 a écrit :
Par hasard, est-ce que cette requête te fait sauter au plafond ? (c'est la requête principale qui liste les messages)


$sql = mysql_query('
SELECT * 
FROM discussion 
WHERE id IN 
(SELECT MAX(id) FROM discussion GROUP BY sujet HAVING epingle = 0) 
ORDER BY id DESC 
LIMIT ' . intval($premierMessage) . ', ' . intval($nombreMsgPage) . '');


pas vraiment mais c'est vrai que les sous-requêtes ne sont pas spécialement ce qu'il y a de plus optimisé.
Si tu pouvais nous transmettre le résultat d'un petit SHOW CREATE TABLE `discussion`; je suis sûr qu'il y a moyen de trouver une requête plus optimisée.
Ah ben tu m'as fait découvrir un nouveau truc (la comande mysql). Voici ce qu'elle dit de la structure :


CREATE TABLE `discussion` (
 `id` smallint(5) unsigned NOT NULL auto_increment,
 `login` varchar(20) collate latin1_general_ci NOT NULL,
 `date` varchar(10) collate latin1_general_ci NOT NULL,
 `heure` time NOT NULL,
 `sujet` varchar(40) collate latin1_general_ci NOT NULL,
 `sujetFormate` varchar(60) collate latin1_general_ci NOT NULL,
 `message` text collate latin1_general_ci NOT NULL,
 `tag` varchar(30) collate latin1_general_ci NOT NULL,
 `idDansSujet` tinyint(3) unsigned NOT NULL,
 `epingle` tinyint(1) NOT NULL,
 `IP` varchar(15) collate latin1_general_ci NOT NULL,
 PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=890 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci


Au passage, je ne sais pas si on peut en faire quelque chose non plus (je crois qu'il est impossible de joindre les 2 tables), voici les options qui me servent à déterminer les statuts lus/non lus/suivis, pour chaque membre :


CREATE TABLE `discussion_options` (
 `id` smallint(5) unsigned NOT NULL auto_increment,
 `login` varchar(20) collate latin1_general_ci NOT NULL,
 `sujet_consulte` varchar(40) collate latin1_general_ci NOT NULL,
 `com_consulte` smallint(6) unsigned NOT NULL,
 `sujet_suivi` tinyint(1) unsigned NOT NULL,
 PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=52 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci

Modifié par Bertrand40 (18 Feb 2011 - 13:42)
@Paolo : C'est bon, j'ai bien compris tes 2 conseils et ils sont appliqués.

Au passage, j'ai supprimé 2 requêtes sql inutiles, pour n'en faire qu'une.

Résultat, Firebug m'indique 2 secondes de gagnées pratiquement, soit environ 2,5 secondes jusqu'au onload. C'est déjà beaucoup mieux.

Ce qui est hallucinant, c'est que sous Chrome il n'y a quasiment pas de délai (moins d'une seconde au onload). Sous Opera pareil, et même sous IE8 & 9. FF3.6 semble vraiment très lent. Même FF4b11 n'est pas aussi rapide que Chrome sur mon site.

Bref, je poursuis le travail. Niveau accessibilité c'est mieux. Petit à petit je rentre dans ces considérations d'accessibilité (javascript, redirections..). Ce qui est dommage c'est qu'on sacrifie l'ergonomie sur l'autel de l'accessibilité. En gros on gâche le plaisir d'une majorité pour satisfaire une minorité. Enfin c'est ce que je comprends.
a écrit :
Ce qui est dommage c'est qu'on sacrifie l'ergonomie sur l'autel de l'accessibilité. En gros on gâche le plaisir d'une majorité pour satisfaire une minorité. Enfin c'est ce que je comprends.

Non, ce n'est pas le but. Le principe est de donner les fonctionnalités de base et l'accès aux contenus à tous et de donner à ceux qui peuvent se le permettre (bande passante etc)
la meilleure expérience possible.

Côté serveur, as tu implémenté un système de cache ? Ça peut améliorer drastiquement les perfs.

Le css statique: sur ton site, le fichier css semble généré dynamiquement, ce qui représente une charge de travail et donc un délai supplémentaire. En le rendant statique, cad en faisant un bête fichier css, tu gagneras encore en perfs.

Edit: et réduis le nbre d'images d'arrière plan (17) en utilisant les sprites
Modifié par paolo (18 Feb 2011 - 16:43)
Grosso modo voici ce que j'ai fait (hormis les requêtes).

Htaccess :

Header unset ETag
FileETag None

<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 7 days"
ExpiresByType image/x-icon "access plus 1 month"
</IfModule>

<IfModule mod_deflate.c>
<FilesMatch "\.(js|css|html|php|jpg|jpeg|png|gif)$">
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>

PS : concernant les sprites, je verrai ça éventuellement en dernier, car là il y a déjà pas mal à faire.
Modifié par Bertrand40 (18 Feb 2011 - 17:28)
Voila la requête qui devrai te donner le même résultat que ta requête + sous-requête :
$sql = mysql_query('
    SELECT `Discussion`.*
    FROM `discussion` AS `Discussion`
    LEFT JOIN `discussion` AS `Discussion_` ON (`Discussion_`.`sujet` = `Discussion`.`sujet` AND `Discussion_`.`idDansSujet` > `Discussion`.`idDansSujet`)
    WHERE `Discussion_`.`id` IS NULL
    AND `Discussion`.`epingle` = 0
    ORDER BY `Discussion`.id DESC
    LIMIT '. (int)$premierMessage .', '. (int)$nombreMsgPage .';
');


Si ça ne donne pas le résultat escompté remplace
`Discussion_`.`idDansSujet` > `Discussion`.`idDansSujet`
par
`Discussion_`.`id` > `Discussion`.`id`
mais si j'ai bien compris ta table, les deux possibilités devrai donner le même résultat.


Pense aussi à mettre des index sur 'sujet' et 'epingle' (et aussi sur 'idDansSujet' si tu l'utilises) et ça même si tu utilises ta requête plutôt que celle-ci
bilhackmac a écrit :
Voila la requête qui devrai te donner le même résultat que ta requête + sous-requête :
$sql = mysql_query('
    SELECT `Discussion`.*
    FROM `discussion` AS `Discussion`
    LEFT JOIN `discussion` AS `Discussion_` ON (`Discussion_`.`sujet` = `Discussion`.`sujet` AND `Discussion_`.`idDansSujet` &gt; `Discussion`.`idDansSujet`)
    WHERE `Discussion_`.`id` IS NULL
    AND `Discussion`.`epingle` = 0
    ORDER BY `Discussion`.id DESC
    LIMIT '. (int)$premierMessage .', '. (int)$nombreMsgPage .';
');


Si ça ne donne pas le résultat escompté remplace
`Discussion_`.`idDansSujet` &gt; `Discussion`.`idDansSujet`
par
`Discussion_`.`id` &gt; `Discussion`.`id`
mais si j'ai bien compris ta table, les deux possibilités devrai donner le même résultat.


Pense aussi à mettre des index sur 'sujet' et 'epingle' (et aussi sur 'idDansSujet' si tu l'utilises) et ça même si tu utilises ta requête plutôt que celle-ci


Wow, hyper impressionnant.... Smiley eek En 2 coups de cuillères à pot tu m'as fait gagner 2 secondes.... Ce qui me gêne c'est que je ne comprends pas la requête, va falloir bien la lire car elle n'est pas aussi lisible (pour moi) que ce que j'avais fait.

Ben écoute merci beaucoup, vraiment. Grâce à tout ça mon site a beaucoup progressé. Pour preuve, et ça convaincra les sceptiques : nous avons gagné entre 3,5 et 4 secondes sur l'affichage de la discussion, soit un affichage complet qui se fait dorénavant en moins de 1 seconde... Jamais je pensais qu'on en arriverait à ce point-là.

Sincèrement merci à tous. Smiley ravi
Modifié par Bertrand40 (19 Feb 2011 - 14:34)
Bertrand40 a écrit :
Wow, hyper impressionnant.... Smiley eek En 2 coups de cuillères à pot tu m'as fait gagner 2 secondes.... Ce qui me gêne c'est que je ne comprends pas la requête, va falloir bien la lire car elle n'est pas aussi lisible (pour moi) que ce que j'avais fait.


Oui j'allais y venir mais j'ai été pris par le temps, j'été au taf… Smiley bawling

Donc l'astuce de cette petite requête, c'est qu'elle boucle sur elle même avec le 'LEFT JOIN'. Chaque enregistrement est donc lié sur un groupe lui correspondant (dans ce cas là, sur 'sujet'), puis chaque groupe est trié suivant un ordre de grandeur (un id, une date… (dans ce cas la 'idDansSujet')).

Ce processus permet d'obtenir une requête qui retourne beaucoup de résultat, mais seul les derniers (premiers si on inverse le signe de grandeur) résultats par groupe ont un id (ou n'importe quel autre champ) dans la table de bouclage qui vaut NULL.

Ansi avec 'WHERE table_de_bouclage.n_importe_quel_champ IS NULL' ont obtient le dernier enregistrement pour chaque groupe.

J'espère avoir été clair. Smiley lol


L'indexation des champs de recherche, 'sujet' et 'idDansSujet', aide aussi beaucoup dans la vitesse d'exécution des requête.





Pour ta deuxième table que tu nous as fait passé, je regarderai ça en revenant du resto… ou demain. Smiley biggol
Modifié par bilhackmac (20 Feb 2011 - 19:49)
Bon je viens d'y jeter un œil, on peut lier les deux tables sur discussion.sujet = discussion_options.sujet_consulte.

Je suppose aussi que com_consulte est en fait l''id' de 'discussion' du dernier message vu pour un sujet pour un utilisateur. (je me trompe ?)

Maintenant la question est : quel résultat veux-tu obtenir ? Smiley cligne
bilhackmac a écrit :

Donc l'astuce de cette petite requête, c'est qu'elle boucle sur elle même avec le 'LEFT JOIN'. Chaque enregistrement est donc lié sur un groupe lui correspondant (dans ce cas là, sur 'sujet'), puis chaque groupe est trié suivant un ordre de grandeur (un id, une date… (dans ce cas la 'idDansSujet')).

Ce processus permet d'obtenir une requête qui retourne beaucoup de résultat, mais seul les derniers (premiers si on inverse le signe de grandeur) résultats par groupe ont un id (ou n'importe quel autre champ) dans la table de bouclage qui vaut NULL.

Ansi avec 'WHERE table_de_bouclage.n_importe_quel_champ IS NULL' ont obtient le dernier enregistrement pour chaque groupe.

J'espère avoir été clair. Smiley lol


Salut ! Oui c'est clairement dit, mais pas clairement compris on va dire. Je vais prendre un stylo, une feuille, et essayer de comprendre car ta requête est diablement efficace..!

bilhackmac a écrit :
Bon je viens d'y jeter un œil, on peut lier les deux tables sur discussion.sujet = discussion_options.sujet_consulte.

Je suppose aussi que com_consulte est en fait l''id' de 'discussion' du dernier message vu pour un sujet pour un utilisateur. (je me trompe ?)

Maintenant la question est : quel résultat veux-tu obtenir ? cligne


En fait j'essaie de lister, dans le même tableau, les sujets consultés, les sujets suivis, et les sujets commentés, d'un membre (pour les besoins de son espace personnel). J'y arrive avec une suite de requêtes, mais ça donne une fois de plus une page extrêmement lourde à charger.

Je suis presque arrivé à une requête unique qui fait ce que je voudrais. Le problème étant le fait que l'intitulé des sujets non commentés n'apparait pas dans le listing.

Voici cette requête :


SELECT *
FROM `discussion_options` DO
LEFT JOIN `discussion` D 
ON D.`sujet` = DO.`sujetConsulte`
AND P.`login` = "' . mysql_real_escape_string($statut) . '"
WHERE DO.`login` = "' . mysql_real_escape_string($statut) . '" 
GROUP BY DO.`sujetConsulte`');


Je serai de retour en fin d'après-midi. Une fois de plus merci de t'attarder sur mon cas, c'est super sympa. Bonne journée. Smiley ravi

PS : Dis, est-ce que ce cours aborde les cas plus évolués que tu appliques ici ? http://sqlpro.developpez.com/cours/sqlaz/jointures/

Il faudrait que je progresse et les sites (genre sdz) n'abordent dans leurs tutos que des cas basiques que je sais faire.
Pages :