09-06-2010, 07:44 AM
(Modification du message : 09-06-2010, 07:47 AM par Sephi-Chan.)
Argorate, tu dois bien avoir des parties de HTML qui peuvent être mises en cache, ne soit pas de mauvaise foi (ça ne fera pas aller ton application plus vite)… Et les micro-optimisations ne limiteront pas le gâchis.
Et c'est là que tu dois te tromper. Exemple dans l'application Spherium (le code source est dans ma signature, ainsi que les chapitres 3 et 4 du pas à pas qui traitent de ce que je vais indiquer). J'ai une page de ce genre :
La carte est simplement construite en HTML. On a une partie constante pour tous les joueurs qui consiste à afficher toutes les sphères vides, c'est la même chose pour tous les joueurs : le HTML généré est mis en cache (cf. page de source de la vue). Le fichier de cache contient ça :
Tu notera que ça fait un paquet de code, quand même, à générer sur chaque page en récupérant la carte, les anneaux de la carte puis les sphères des anneaux. Alors que finalement c'est constant. Et bien je le cache en faisant simplement :
Ensuite, la deuxième couche affiche (sur la précédente) les bâtiments construits par le joueur (les sphères de couleur). Et là aussi, ces liste est constante pour chaque joueur, elle ne change que quand l'utilisateur crée un bâtiment. Ainsi, le cache de la liste des bâtiments de l'utilisateur #1 est :
Donc je fais ça :
Grâce à ActiveRecord 3 (embarqué dans Rails 3), les requêtes sont réalisées au dernier moment, quand on cherche à itérer sur les bâtiments. Du coup si le cache existe, les requêtes ne sont même pas effectuées.
Et quand je recycle ou construit un bâtiment (ou quand il sera détruit dans un combat), j'ai simplement à appeler la méthode expire_fragments), comme le montre le code de mon contrôleur Buildings.
Et ce déclenchement des requêtes au plus tard, vous n'êtes pas prêts de le faire avec un système maison (déjà qu'aucun ORM pour PHP ne va aussi loin dans le lazy loading…), ni ce système de cache très simple d'utilisation.
Ça vaut le coup de consommer un peu plus de RAM et d'avoir une application plus intelligente, non ?
Sephi-Chan
(08-06-2010, 11:59 PM)php_addict a écrit :(08-06-2010, 11:20 PM)Sephi-Chan a écrit : Et c'est là que j'aimerai bien voir du code de toi ou d'Argorate. Comment vous faîtes ça ?
effectivement les pages de mon projet sont générées à chaque fois (pour ce qui est des données du joueur, par exemple les batiments du joueur. donc si tu clique sur un batiment 10 fois de suite, alors il y aura interogation de la base de donnée à chaque fois.
par contre evidement une grosse partie du code HTML n'est pas générée puisque il fait partie d'un fichier VUE (mvc) et donc une bonne partie du HTML est simplement lu
je n'ai pas de système de mise en cache du HTML des pages générées mais pour mon projet je ne suis pas certain que cela ai un réel interet (par exemple si un joueur affiche l'un de ces propres batiment il va bien falloir tester qu'il existe encore donc interroger la base de donnée)
pour le moment je n'ai pas vu quelles sont les pages de mon site qui auraient besoin d'un systeme de cache (je n'ai pas encore attaqué la partie statistiques, classements, etc... du jeu par exemple)
Et c'est là que tu dois te tromper. Exemple dans l'application Spherium (le code source est dans ma signature, ainsi que les chapitres 3 et 4 du pas à pas qui traitent de ce que je vais indiquer). J'ai une page de ce genre :
La carte est simplement construite en HTML. On a une partie constante pour tous les joueurs qui consiste à afficher toutes les sphères vides, c'est la même chose pour tous les joueurs : le HTML généré est mis en cache (cf. page de source de la vue). Le fichier de cache contient ça :
<div id="map">
<div class="ring" data-ring-index="0" id="ring-0">
<a class="sphere sphere-0-0" data-ring-index="0" data-sphere-index="0" href="/game/buildings/rings/0/spheres/0" id="sphere-0-0"/>
</div>
<div class="ring" data-ring-index="1" id="ring-1">
<a class="sphere sphere-1-0" data-ring-index="1" data-sphere-index="0" href="/game/buildings/rings/1/spheres/0" id="sphere-1-0"/>
<a class="sphere sphere-1-1" data-ring-index="1" data-sphere-index="1" href="/game/buildings/rings/1/spheres/1" id="sphere-1-1"/>
<a class="sphere sphere-1-2" data-ring-index="1" data-sphere-index="2" href="/game/buildings/rings/1/spheres/2" id="sphere-1-2"/>
<a class="sphere sphere-1-3" data-ring-index="1" data-sphere-index="3" href="/game/buildings/rings/1/spheres/3" id="sphere-1-3"/>
<a class="sphere sphere-1-4" data-ring-index="1" data-sphere-index="4" href="/game/buildings/rings/1/spheres/4" id="sphere-1-4"/>
<a class="sphere sphere-1-5" data-ring-index="1" data-sphere-index="5" href="/game/buildings/rings/1/spheres/5" id="sphere-1-5"/>
<a class="sphere sphere-1-6" data-ring-index="1" data-sphere-index="6" href="/game/buildings/rings/1/spheres/6" id="sphere-1-6"/>
<a class="sphere sphere-1-7" data-ring-index="1" data-sphere-index="7" href="/game/buildings/rings/1/spheres/7" id="sphere-1-7"/>
</div>
<div class="ring" data-ring-index="2" id="ring-2">
<a class="sphere sphere-2-0" data-ring-index="2" data-sphere-index="0" href="/game/buildings/rings/2/spheres/0" id="sphere-2-0"/>
<a class="sphere sphere-2-1" data-ring-index="2" data-sphere-index="1" href="/game/buildings/rings/2/spheres/1" id="sphere-2-1"/>
<a class="sphere sphere-2-2" data-ring-index="2" data-sphere-index="2" href="/game/buildings/rings/2/spheres/2" id="sphere-2-2"/>
<a class="sphere sphere-2-3" data-ring-index="2" data-sphere-index="3" href="/game/buildings/rings/2/spheres/3" id="sphere-2-3"/>
<a class="sphere sphere-2-4" data-ring-index="2" data-sphere-index="4" href="/game/buildings/rings/2/spheres/4" id="sphere-2-4"/>
<a class="sphere sphere-2-5" data-ring-index="2" data-sphere-index="5" href="/game/buildings/rings/2/spheres/5" id="sphere-2-5"/>
<a class="sphere sphere-2-6" data-ring-index="2" data-sphere-index="6" href="/game/buildings/rings/2/spheres/6" id="sphere-2-6"/>
<a class="sphere sphere-2-7" data-ring-index="2" data-sphere-index="7" href="/game/buildings/rings/2/spheres/7" id="sphere-2-7"/>
<a class="sphere sphere-2-8" data-ring-index="2" data-sphere-index="8" href="/game/buildings/rings/2/spheres/8" id="sphere-2-8"/>
<a class="sphere sphere-2-9" data-ring-index="2" data-sphere-index="9" href="/game/buildings/rings/2/spheres/9" id="sphere-2-9"/>
<a class="sphere sphere-2-10" data-ring-index="2" data-sphere-index="10" href="/game/buildings/rings/2/spheres/10" id="sphere-2-10"/>
<a class="sphere sphere-2-11" data-ring-index="2" data-sphere-index="11" href="/game/buildings/rings/2/spheres/11" id="sphere-2-11"/>
</div>
<div class="ring" data-ring-index="3" id="ring-3">
<a class="sphere sphere-3-0" data-ring-index="3" data-sphere-index="0" href="/game/buildings/rings/3/spheres/0" id="sphere-3-0"/>
<a class="sphere sphere-3-1" data-ring-index="3" data-sphere-index="1" href="/game/buildings/rings/3/spheres/1" id="sphere-3-1"/>
<a class="sphere sphere-3-2" data-ring-index="3" data-sphere-index="2" href="/game/buildings/rings/3/spheres/2" id="sphere-3-2"/>
<a class="sphere sphere-3-3" data-ring-index="3" data-sphere-index="3" href="/game/buildings/rings/3/spheres/3" id="sphere-3-3"/>
<a class="sphere sphere-3-4" data-ring-index="3" data-sphere-index="4" href="/game/buildings/rings/3/spheres/4" id="sphere-3-4"/>
<a class="sphere sphere-3-5" data-ring-index="3" data-sphere-index="5" href="/game/buildings/rings/3/spheres/5" id="sphere-3-5"/>
<a class="sphere sphere-3-6" data-ring-index="3" data-sphere-index="6" href="/game/buildings/rings/3/spheres/6" id="sphere-3-6"/>
<a class="sphere sphere-3-7" data-ring-index="3" data-sphere-index="7" href="/game/buildings/rings/3/spheres/7" id="sphere-3-7"/>
<a class="sphere sphere-3-8" data-ring-index="3" data-sphere-index="8" href="/game/buildings/rings/3/spheres/8" id="sphere-3-8"/>
<a class="sphere sphere-3-9" data-ring-index="3" data-sphere-index="9" href="/game/buildings/rings/3/spheres/9" id="sphere-3-9"/>
<a class="sphere sphere-3-10" data-ring-index="3" data-sphere-index="10" href="/game/buildings/rings/3/spheres/10" id="sphere-3-10"/>
<a class="sphere sphere-3-11" data-ring-index="3" data-sphere-index="11" href="/game/buildings/rings/3/spheres/11" id="sphere-3-11"/>
<a class="sphere sphere-3-12" data-ring-index="3" data-sphere-index="12" href="/game/buildings/rings/3/spheres/12" id="sphere-3-12"/>
<a class="sphere sphere-3-13" data-ring-index="3" data-sphere-index="13" href="/game/buildings/rings/3/spheres/13" id="sphere-3-13"/>
<a class="sphere sphere-3-14" data-ring-index="3" data-sphere-index="14" href="/game/buildings/rings/3/spheres/14" id="sphere-3-14"/>
<a class="sphere sphere-3-15" data-ring-index="3" data-sphere-index="15" href="/game/buildings/rings/3/spheres/15" id="sphere-3-15"/>
</div>
</div>
Tu notera que ça fait un paquet de code, quand même, à générer sur chaque page en récupérant la carte, les anneaux de la carte puis les sphères des anneaux. Alors que finalement c'est constant. Et bien je le cache en faisant simplement :
<% cache "base_for_map_#{@map.id}" do %>
<%= map_base_tag(@map) %>
<% end %>
Ensuite, la deuxième couche affiche (sur la précédente) les bâtiments construits par le joueur (les sphères de couleur). Et là aussi, ces liste est constante pour chaque joueur, elle ne change que quand l'utilisateur crée un bâtiment. Ainsi, le cache de la liste des bâtiments de l'utilisateur #1 est :
<a class="building sphere sphere-3-1 energy_well" data-ring-index="3" data-sphere-index="1" href="/game/buildings/rings/3/spheres/1" id="building-1"/>
<a class="building sphere sphere-2-2 energy_well" data-ring-index="2" data-sphere-index="2" href="/game/buildings/rings/2/spheres/2" id="building-2"/>
<a class="building sphere sphere-3-13 energy_well" data-ring-index="3" data-sphere-index="13" href="/game/buildings/rings/3/spheres/13" id="building-3"/>
<a class="building sphere sphere-3-9 energy_well" data-ring-index="3" data-sphere-index="9" href="/game/buildings/rings/3/spheres/9" id="building-4"/>
<a class="building sphere sphere-2-0 barracks" data-ring-index="2" data-sphere-index="0" href="/game/buildings/rings/2/spheres/0" id="building-5"/>
<a class="building sphere sphere-1-2 barracks" data-ring-index="1" data-sphere-index="2" href="/game/buildings/rings/1/spheres/2" id="building-6"/>
<a class="building sphere sphere-3-11 house" data-ring-index="3" data-sphere-index="11" href="/game/buildings/rings/3/spheres/11" id="building-11"/>
<a class="building sphere sphere-3-4 energy_well" data-ring-index="3" data-sphere-index="4" href="/game/buildings/rings/3/spheres/4" id="building-14"/>
<a class="building sphere sphere-3-14 energy_well" data-ring-index="3" data-sphere-index="14" href="/game/buildings/rings/3/spheres/14" id="building-23"/>
<a class="building sphere sphere-3-2 barracks" data-ring-index="3" data-sphere-index="2" href="/game/buildings/rings/3/spheres/2" id="building-25"/>
<a class="building sphere sphere-3-7 energy_well" data-ring-index="3" data-sphere-index="7" href="/game/buildings/rings/3/spheres/7" id="building-26"/>
<a class="building sphere sphere-3-12 energy_well" data-ring-index="3" data-sphere-index="12" href="/game/buildings/rings/3/spheres/12" id="building-27"/>
<a class="building sphere sphere-3-3 energy_well" data-ring-index="3" data-sphere-index="3" href="/game/buildings/rings/3/spheres/3" id="building-28"/>
Donc je fais ça :
<% cache "buildings_map_of_user_#{current_user.id}" do %>
<% @buildings_for_map.each do |building| %>
<%= building_tag(building) %>
<% end %>
<% end %>
Grâce à ActiveRecord 3 (embarqué dans Rails 3), les requêtes sont réalisées au dernier moment, quand on cherche à itérer sur les bâtiments. Du coup si le cache existe, les requêtes ne sont même pas effectuées.
Et quand je recycle ou construit un bâtiment (ou quand il sera détruit dans un combat), j'ai simplement à appeler la méthode expire_fragments), comme le montre le code de mon contrôleur Buildings.
Et ce déclenchement des requêtes au plus tard, vous n'êtes pas prêts de le faire avec un système maison (déjà qu'aucun ORM pour PHP ne va aussi loin dans le lazy loading…), ni ce système de cache très simple d'utilisation.
Ça vaut le coup de consommer un peu plus de RAM et d'avoir une application plus intelligente, non ?
Sephi-Chan