get_option () vs get_theme_mod (): Pourquoi est-ce plus lent?


17

J'utilise get_theme_mod()depuis un certain temps certains de mes projets. J'ai décidé de profiter de l'API de personnalisation de thème 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 prenait beaucoup de temps à charger. Grâce à de nombreux essais et erreurs au cours de mon enquête, j'ai décidé d'essayer de désactiver le typelors 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 get_theme_mod()appels vers get_option(), j'ai remarqué une augmentation très importante de la vitesse en utilisant cette dernière configuration par opposition à la première sur le frontend et surtout dans le Customizer sur le backend. J'ai cherché dans le noyau WordPress dans le but d'essayer de trouver une réponse pour expliquer pourquoi, mais je n'arrive pas à discerner quel est le blocage particulier dans ce scénario.

Toutes les informations que la communauté pourrait avoir en ce qui concerne l' get_option()exécution beaucoup plus rapide get_theme_mod()seraient grandement appréciées.


1
Si vous jetez un coup d' oeil dans /wp-includesà option.phpget_option()est défini, et theme.phpget_theme_mod()est défini, vous pouvez voir que ce dernier fait appelle get_option()lui - même, agissant comme une extension de celui - ci qui applique également les filtres nécessaires. Pourrait expliquer pourquoi c'est plus lent.
Jody Heavener

1
Jody, je le pensais moi-même, mais j'ai l'impression que le simple fait de référencer get_option()et d'appliquer des filtres ne devrait pas ralentir autant que par le passé. Certainement un excellent point de départ, mais je me demande s'il n'y a rien d'autre dans les travaux ici.
ntg2

3
Il n'y a aucune raison de différence de vitesse, donc je soupçonne que quelque chose d'autre est à l'origine de vos différences perçues. Les mods de thème sont stockés sous forme d'options eux-mêmes.
Otto

Le processus de sérialisation / désérialisation dans la récupération du mod individuel pourrait-il y jouer un rôle? Je suis curieux de savoir si ce travail supplémentaire pour extraire le mod pourrait être un blocage plutôt que de simplement récupérer l'option sans avoir besoin de le faire. Lors du passage de get_theme_mod()la get_option()vitesse de tous les projets a doublé en moyenne sur les deux frontend et dans le Customizer. Ce fut le seul changement qui a été fait dans le but de l'isoler de tout autre effet secondaire.
ntg2

Réponses:


19

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

Les mods de thème sont stockés en tant qu'options. Donc, en substance, les fonctions theme_mod sont des wrappers autour des fonctions options.

Tout d'abord, sachez que les paramètres theme_mod sont stockés sous forme de tableau dans une seule option, codée avec le nom du thème spécifique. Donc, si je fais ça:

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

Ensuite, ce que j'obtiens réellement dans la base de données est une seule ligne d'options avec le nom de theme_mods_themename qui contient un tableau sérialisé avec ('aaa' => 123, 'bbb' => 456).

Maintenant, ce get_theme_modsera plus lent, car il passe en fait deux get_optionappels. Tout d'abord, il obtient le nom du thème. Ensuite, il obtient l' theme_mods_themenameoption. Alors là, c'est une perte de vitesse de 50%. Le reste du travail effectué repose principalement sur des filtres, en ce sens qu'il y a un appel de filtre supplémentaire, mais à moins que vous n'ayez quelque chose sur ce filtre, c'est un peu insignifiant.

Notez que le système d'options stocke les données récupérées dans le cache d'objets, donc il ne fait pas plusieurs appels de base de données ici. Seule la première utilisation entraîne un hit de base de données.

Le set_theme_modsera un peu plus lent car il fait ces deux mêmes appels d'options get, puis il fait un autre get_optionappel pour obtenir à nouveau le nom du thème, puis il le fait update_optionavec l'ensemble complet des options maintenant modifiées. Cela provoque une mise à jour de la base de données, et le fait qu'il envoie beaucoup plus de données peut en effet être la cause d'un ralentissement notable. La mise à jour de quelques octets est plus rapide que la mise à jour d'une ligne plus grande. Mais pas autant que vous le remarqueriez habituellement. À moins que vous ayez beaucoup de paramètres ...

Les fonctions de mod de thème sont probablement dues à une optimisation globale, certes, mais néanmoins vous devez toujours les utiliser au lieu de get_option et ainsi parce que les thèmes enfants.

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

Si j'ai un thème appelé "AAA" et que j'en fais un thème enfant appelé "BBB" pour une utilisation sur un autre site, alors mon thème "AAA" pourrait utiliser une option nommée "exemple". Lorsque je mets à jour un site et qu'il met à jour mon option, la même option s'appliquera désormais à mon thème enfant. Et si je ne le voulais pas? Et si je voulais que le thème enfant utilise un autre ensemble de paramètres d'options?

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" du site utilise son propre ensemble de paramètres. Je peux basculer d'avant en arrière et les paramètres ne sont pas transférés entre eux, ils restent comme je les ai définis. Plus simple, plus évident, plus intuitif.

Et si un futur changement de noyau ou plugin modifie le fonctionnement de theme_mods, alors vous en tirerez automatiquement les bénéfices sans aucun changement. Les emballages vont toujours être plus lents, c'est inévitable, c'est la nature des emballages. Néanmoins, vous écrivez toujours du code PHP, pas du 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 se soucier de la façon dont leurs options sont stockées dans la base de données ou du fonctionnement de la dénomination. Les fonctions theme_mod fournissent une solution plus simple et plus propre.


3

get_theme_modest juste un emballage autour get_option. En théorie, car il s'agit d'une autre couche d'abstraction, cela fonctionnera plus lentement, mais en pratique, la différence ne devrait pas être suffisamment grande pour être remarquée par un humain.

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


1

Pourrait-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, mon temps de chargement du Customizer est passé d'environ 3 s à environ 0,5 s lors du passage à get_optionoverget_theme_mod

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

résultats de test ( https://gist.github.com/anonymous/d98a46d00d52d40e7dec )

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


1

Vous pouvez TESTER LE TEMPS de get_option(100 itérations) en utilisant ce code (inséré functions.phpou 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;
}   




Une autre pensée

Je ne sais pas, si cela fait une différence (peut-être que les développeurs Wordpress le savent mieux), mais je pensais que si un site Web a un trafic élevé et à chaque chargement de page, il doit obtenir des centaines d'options, et si je vais rejoindre de nombreuses options en une seule 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 rendra-t-il un site plus rapide?


2
C'est exactement ce que fait déjà get_theme_mod. Tous les mods de thème sont déjà réunis en une seule option. Chaque fois que vous appelez get_theme_mod, il effectue deux appels de base de données la première fois et aucun appel de base de données par la suite.
Otto

0

TL; DR: Si vous êtes développeur de thème, vous devez utiliser get_theme_mod

Réponse complète:

Si vous avez 100 appels get_option, il faut 100 requêtes à votre base de données.

Si vous avez 100 appels get_theme_mod, il ne faut qu'une seule requête à votre base de données.

Pourquoi? Parce que tous les mods de thème sont stockés dans une seule ligne de base de données et ne seront appelés qu'une seule, tandis que chaque option est une ligne et 100 appels get_option entraîneront 100 requêtes de base de données et bien sûr, cela ralentit votre site.

Si votre thème a beaucoup d'options, utilisez get_theme_mod réduira considérablement votre numéro de requête dans la base de données.

Vous pouvez vérifier les performances et le nombre de requêtes par Query Monitor Plugin

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.