get_option () vs get_theme_mod (): ¿Por qué es uno más lento?

17

Lo he estado usando get_theme_mod()durante algún tiempo en varios proyectos míos. Decidí aprovechar la API de personalización de temas en WordPress v3.4 una vez que estaba disponible, ya que sentí que era una herramienta indispensable para mis clientes.

Después de un tiempo, comencé a notar que mis sitios se sentían un poco más lentos de lo habitual, y el Personalizador en particular tardó bastante tiempo en cargarse. A través de un montón de prueba y error durante mi investigación, decidí intentar cambiar el typeal registrar mi configuración (es decir $wp_customize->add_setting()) de theme_moda option.

Una vez que hice esto y cambié todas mis get_theme_mod()llamadas a get_option(), noté un aumento muy significativo en la velocidad usando la última configuración en lugar de la primera en la interfaz y especialmente en el Personalizador en el back-end. He estado buscando en el núcleo de WordPress en un esfuerzo por tratar de encontrar una respuesta de por qué esto es así, pero parece que no puedo discernir cuál es el bloqueo particular en este escenario.

Cualquier idea que pueda tener la comunidad con respecto al get_option()rendimiento significativamente más rápido de get_theme_mod()lo que sería muy apreciada.

ntg2
fuente
1
Si se echa un vistazo en /wp-includesen option.phpdonde get_option()se define, y en theme.phpdonde get_theme_mod()se define, se puede ver que este último hecho llame get_option()sí, actuando como una extensión de la misma que se aplica también a cualquier filtros necesarios. Podría explicar por qué es más lento.
Jody Heavener
1
Jody, pensé eso, pero parece que simplemente hacer referencia get_option()y aplicar algunos filtros no debería hacer que se desacelere tan significativamente como lo fue. Ciertamente es un gran punto de partida, pero me pregunto si no hay algo más en proceso aquí.
ntg2
3
No hay ninguna razón para ningún tipo de diferencia de velocidad allí, por lo que sospecho que algo más está causando sus diferencias percibidas. Las modificaciones de tema se almacenan como opciones en sí mismas.
Otto
¿Podría el proceso de serialización / deserialización para obtener el mod individual desempeñar un papel en él de alguna manera? Tengo curiosidad por saber si ese trabajo adicional para extraer el mod podría ser un bloqueo en lugar de simplemente buscar la opción sin necesidad de hacerlo. Al realizar el cambio de get_theme_mod()a get_option()la velocidad de todos los proyectos se duplicó en promedio tanto en el frontend y en el personalizador. Este fue el único cambio que se realizó en un esfuerzo por aislarlo de cualquier otro efecto secundario.
ntg2

Respuestas:

19

La respuesta es sí, las funciones de theme_mod serán más lentas, pero no significativamente, y los beneficios superan las diferencias.

Las modificaciones temáticas se almacenan como opciones. Entonces, en esencia, las funciones theme_mod son envoltorios alrededor de las funciones de opciones.

Primero, comprenda que la configuración de theme_mod se almacena como una matriz en una sola opción, asociada al nombre del tema específico. Entonces, si hago esto:

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

Entonces, lo que realmente obtengo en la base de datos es una sola fila de opciones con el nombre de theme_mods_themename que contiene una matriz serializada con ('aaa' => 123, 'bbb' => 456) en ella.

Ahora, get_theme_modserá más lento porque en realidad está haciendo dos get_optionllamadas. Primero, obtiene el nombre del tema. Entonces, obtiene la theme_mods_themenameopción. Entonces, justo ahí, hay una pérdida de velocidad del 50%. El resto del trabajo realizado se basa principalmente en filtros, ya que hay una llamada de filtro adicional, pero a menos que tenga algo en ese filtro, esto es un poco insignificante.

Tenga en cuenta que el sistema de opciones almacena los datos recuperados en el caché de objetos, por lo que no está haciendo llamadas a múltiples bases de datos aquí. Solo el primer uso da como resultado un acierto en la base de datos.

El set_theme_modserá algo más lento, ya que hace esos mismos dos consigue opciones llamadas, entonces tiene otra get_optionllamada para obtener el nombre del tema nuevo, y luego lo hace update_optioncon el conjunto completo de opciones ahora cambiado. Esto provoca una actualización de la base de datos, y el hecho de que está enviando muchos más datos puede ser la causa de una desaceleración notable. Actualizar unos pocos bytes es más rápido que actualizar una fila más grande. Pero no tanto como notarías, por lo general. A menos que tenga una gran cantidad de configuraciones ...

Las funciones de mod de tema probablemente se deben optimizar en general, sin embargo, sin embargo, aún debe usarlas en lugar de get_option y, como así, temas secundarios.

El problema con el uso de filas de opciones directamente es que las está usando directamente y usando nombres de teclas específicos para su configuración.

Si tengo un tema llamado "AAA" y hago un tema secundario llamado "BBB" para usar en otro sitio, entonces mi tema "AAA" podría usar una opción llamada "ejemplo". Cuando actualizo un sitio y actualiza mi opción, la misma opción ahora se aplicará al tema de mi hijo. ¿Qué pasa si no quiero que lo haga? ¿Qué sucede si quisiera que el tema secundario usara un conjunto diferente de configuraciones de opciones?

Las modificaciones de tema, al incluir el nombre real del tema (y no un valor codificado) como parte de la clave, aseguran que cada "tema" en el sitio use su propio conjunto de configuraciones. Puedo cambiar de un lado a otro y la configuración no se transfiere entre ellos, se quedan como los configuro. Más simple, más obvio, más intuitivo.

Y si algún cambio en el núcleo o plugin en el futuro modifica el funcionamiento de theme_mods, automáticamente obtendrá los beneficios de eso sin ningún cambio. Los envoltorios siempre serán más lentos, eso es inevitable, es la naturaleza de los envoltorios. Sin embargo, todavía está escribiendo código PHP, no lenguaje de máquina. Usamos envoltorios como este para simplificar las cosas y separar la funcionalidad. Los temas no deberían necesitar saber, o importarles, cómo se almacenan sus opciones en la base de datos, o cómo funcionan los nombres. Las funciones theme_mod proporcionan una solución más simple que es más limpia.

Otón
fuente
3

get_theme_modes solo una envoltura get_option. En teoría, debido a que es otra capa de abstracción, funcionará más lentamente, pero en la práctica la diferencia no debería ser lo suficientemente grande como para ser notada por un humano.

Las diferencias de velocidad reales pueden ser causadas si tiene algún código lento enganchado en los ganchos theme_mod.

Mark Kaplun
fuente
1

¿Podría haber algo sucediendo en el Personalizador entonces? Estoy viendo lo mismo que el OP aquí.

Puedo confirmar que con alrededor de 30 opciones, el tiempo de carga de mi Personalizador se redujo de alrededor de 3 segundos a alrededor de .5 segundos al cambiar a get_optionmás deget_theme_mod

Al llamar a los métodos directamente, veo una diferencia de 2 ms.

resultados de la prueba ( https://gist.github.com/anonymous/d98a46d00d52d40e7dec )

Puede que no se note cuando compara las API directamente, pero debe haber algo con la forma en que se utilizan en el Personalizador.

VykRevler
fuente
1

Puede PROBAR EL TIEMPO de get_option(100 iteraciones) usando este código (puesto functions.phpo en algún lugar):

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;
}   




Otros pensamientos

No sé, si hace la diferencia (tal vez los desarrolladores de Wordpress lo conozcan mejor), pero pensé que si un sitio web tiene ALTO tráfico, y en cada carga de página, necesita obtener cientos de opciones, entonces, ¿qué pasaría si me uniera? muchas opciones en una get_option? Me gusta esto:

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

luego :

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

¿Esto hará que un sitio sea un poco más rápido?

T.Todua
fuente
2
Eso es exactamente lo que ya hace get_theme_mod. Todos los mods de tema ya están unidos en una sola opción. Cada vez que llama a get_theme_mod, realiza dos llamadas a la base de datos la primera vez y luego cero llamadas a la base de datos.
Otto
0

TL; DR: si eres un desarrollador de temas, debes usar get_theme_mod

Respuesta completa:

Si tiene 100 llamadas get_option, toma 100 consultas a su base de datos.

Si tiene 100 llamadas get_theme_mod, solo necesita 1 consulta a su base de datos.

¿Por qué? Debido a que todas las modificaciones de tema se almacenan en una sola fila de la base de datos y se llamarán solo una, mientras que cada opción es una fila y 100 llamadas get_option generarán 100 consultas en la base de datos y, por supuesto, ralentizará su sitio.

Si su tema tiene muchas opciones, use get_theme_mod reducirá significativamente su número de consulta a la base de datos.

Puede verificar el rendimiento y el número de consultas mediante el complemento de monitor de consultas

Tran Cuong
fuente