web-dev-qa-db-fra.com

get_option () vs get_theme_mod (): Pourquoi on est plus lent?

J'utilise get_theme_mod() depuis un certain temps dans divers de mes projets. J'ai décidé de tirer parti de l'API Thème Personnalisation dans WordPress v3.4 une fois qu'elle était disponible, car je pensais que c'était un outil indispensable pour mes clients.

Après un certain temps, j'ai commencé à remarquer que mes sites se sentaient un peu plus lents que d'habitude, et le Customizer, en particulier, a pris beaucoup de temps à charger. Après de nombreuses tentatives d’essais et d’erreur au cours de mon enquête, j’ai décidé de remplacer le type lors de l’enregistrement de mes paramètres (c'est-à-dire $wp_customize->add_setting()) de theme_mod à option.

Une fois que j’ai fait cela et échangé tous mes appels get_theme_mod() en get_option(), j’ai remarqué une très importante augmentation de la vitesse en utilisant la dernière configuration par opposition à la précédente sur le frontend et particulièrement dans le Customizer sur le backend. J'ai parcouru le cœur de WordPress afin d'essayer de trouver une réponse à cette question, mais je n'arrive pas à discerner quelle est la situation particulière de ce scénario.

Toute idée de la part de la communauté en ce qui concerne get_option() effectuerait beaucoup plus rapidement que get_theme_mod() serait grandement appréciée.

15
ntg2

La réponse est que les fonctions theme_mod seront plus lentes, mais pas de manière significative, et que les avantages l'emporteront sur les différences.

Les mods de thème sont stockés en tant qu'options. Ainsi, les fonctions theme_mod sont essentiellement des enveloppes autour des fonctions options.

Commencez par comprendre que les paramètres theme_mod sont stockés sous forme de tableau dans une seule option, associée au nom de thème spécifique. Donc, si je fais ceci:

set_theme_mod('aaa',123);
set_theme_mod('bbb',456);

Ensuite, ce que je reçois dans la base de données est une seule ligne d’options portant le nom theme_mods_themename, qui contient un tableau sérialisé contenant ('aaa' => 123, 'bbb' => 456).

Maintenant, get_theme_mod sera plus lent car il effectue en réalité deux appels get_option. Tout d'abord, il obtient le nom du thème. Ensuite, il obtient l'option theme_mods_themename. Il y a donc une perte de vitesse de 50%. Le reste du travail consiste principalement en filtres, dans la mesure où il existe un appel de filtre supplémentaire, mais à moins que ce filtre ne comporte quelque chose, il est un peu insignifiant.

Notez que le système d'options stocke les données extraites dans le cache d'objets. Par conséquent, il ne fait pas plusieurs appels à la base de données ici. Seule la première utilisation aboutit à un hit de base de données.

Le set_theme_mod sera un peu plus lent car il effectue ces deux mêmes appels d’options, puis effectue un autre appel get_option pour récupérer le nom du thème, puis effectue update_option avec le jeu complet d’options modifiées. Cela provoque une mise à jour de la base de données et le fait qu’elle envoie beaucoup plus de données peut en effet être à l’origine d’un ralentissement notable. La mise à jour de quelques octets est plus rapide que la mise à jour d'une rangée plus grande. Mais pas autant que vous le remarqueriez, habituellement. Sauf si vous avez énormément de réglages ...

Les fonctions de mod de thème sont probablement dues à une optimisation globale, certes, mais vous devriez néanmoins les utiliser à la place de get_option et autres, parce que des thèmes enfants.

Le problème lié à l’utilisation directe des lignes d’options est que vous les utilisez directement et que vous utilisez des noms de clé spécifiques pour vos paramètres.

Si j'ai un thème appelé "AAA" et que je crée un thème enfant appelé "BBB" à utiliser sur un autre site, mon thème "AAA" peut utiliser une option nommée "exemple". Lorsque je mets à jour un site et que mon option est mise à jour, la même option s’applique désormais à mon thème enfant. Et si je ne voulais pas le faire? Et si je voulais que le thème enfant utilise un ensemble différent de paramètres d'option?

Les mods de thème, en incluant le nom du thème réel (et non une valeur codée en dur) dans la clé, garantissent que chaque "thème" sur le site utilise son propre ensemble de paramètres. Je peux basculer et les paramètres ne sont pas transférés entre eux, ils restent comme je les ai configurés. Plus simple, plus évident, plus intuitif.

Et si un changement ou un plugin central futur modifie le fonctionnement de theme_mods, vous en profiterez automatiquement, sans aucun changement. Les emballages seront toujours plus lents, c'est inévitable, c'est la nature des emballages. Néanmoins, vous écrivez toujours PHP code, pas le langage machine. Nous utilisons des wrappers comme celui-ci pour simplifier les choses et séparer les fonctionnalités. Les thèmes ne devraient pas avoir besoin de savoir ou de savoir comment leurs options sont stockées dans la base de données ou comment la dénomination fonctionne. Les fonctions theme_mod fournissent une solution plus simple, plus propre.

19
Otto

get_theme_mod est juste un wrapper autour de get_option. En théorie, parce que c'est une autre couche d'abstraction, cela fonctionnera plus lentement, mais en pratique, la différence ne devrait pas être assez grande pour être remarquée par un humain.

Des différences de vitesse réelles peuvent être causées si du code lent est accroché aux hooks theme_mod.

3
Mark Kaplun

Vous pouvez TEST THE TIME of get_option (100 itérations) en utilisant ce code (mis dans functions.php ou quelque part):

add_action('wp','My_Test');
function My_Test(){
    var_dump(microtime(true));
    for ($i=1; $i<100; $i++) { get_option('blogdescription'); }
    var_dump(microtime(true));
    for ($i=1; $i<100; $i++) { get_theme_mod('blogdescription'); }
    var_dump(microtime(true));
    exit;
}   




Autres pensées

Je ne sais pas, si cela fait une différence (peut-être que les développeurs de Wordpress le savent mieux), mais je pensais que si un site Web avait un trafic élevé, et chaque chargement de page, il devait comporter des centaines d'options, alors si je rejoignais beaucoup d'options dans un get_option? comme ça:

update_option('my_extra_optss',  array(
      'myNAME' => 'George',
      'myAGE'  => 43 ));

puis :

$x = get_option('my_extra_optss');
$x['myNAME'];
$x['myAGE'];
................

cela va-t-il rendre un site un peu plus rapide?

1
T.Todua

Peut-il y avoir quelque chose dans Customizer alors? Je vois la même chose que l'OP ici.

Je peux confirmer qu'avec environ 30 options, le temps de chargement de Customizer est passé de 3 s à environ 0,5 lors du passage à get_option au-dessus de get_theme_mod.

En appelant directement les méthodes, je vois une différence de 2ms.

test_results ( https://Gist.github.com/anonymous/d98a46d00d52d40e7dec )

Cela ne se remarque peut-être pas lorsque vous comparez directement les API, mais il doit y avoir quelque chose à propos de la façon dont elles sont utilisées dans Customizer.

0
VykRevler