get_option () vs get_theme_mod (): Por que um é mais lento?


17

Estou usando get_theme_mod()há algum tempo em vários projetos meus. Decidi aproveitar a API de personalização de temas no WordPress v3.4, uma vez que estava disponível, pois considerava uma ferramenta indispensável para meus clientes usarem.

Depois de algum tempo, comecei a perceber que meus sites estavam se sentindo um pouco mais lentos do que o habitual, e o Customizer, em particular, levou muito tempo para carregar. Com várias tentativas e erros durante minha investigação, decidi tentar mudar o typeregistro das minhas configurações (por exemplo $wp_customize->add_setting()) de theme_modpara option.

Depois que fiz isso e troquei todas as minhas get_theme_mod()chamadas para get_option(), notei um aumento muito significativo na velocidade usando a última configuração, em oposição à anterior no front-end e principalmente no Customizer no back-end. Eu estive pesquisando o núcleo do WordPress em um esforço para tentar descobrir uma resposta para isso, mas parece que não consigo discernir qual é o problema específico nesse cenário.

Quaisquer informações que a comunidade possa ter em relação ao get_option()desempenho significativamente mais rápido do que get_theme_mod()seria muito apreciado.


1
Se você der uma olhada em /wp-includesem option.phponde get_option()é definido e, theme.phponde get_theme_mod()é definido, você pode ver que este último realmente chama get_option()em si, agindo como uma extensão dela que também se aplica todos os filtros necessários. Poderia explicar por que é mais lento.
— precisa

1
Jody, pensei nisso, mas parece que simplesmente fazer referência get_option()e aplicar alguns filtros não deve torná-lo mais lento do que era. Certamente um ótimo ponto de partida, mas estou me perguntando se não há mais nada em andamento aqui.
— Ntg2 19/07/2014

3
Não há razão para qualquer tipo de diferença de velocidade por lá, então suspeito que algo mais esteja causando suas diferenças percebidas. Os mods de tema são armazenados como opções.
— Otto

Poderia o processo de serialização / desserialização na busca do mod individual desempenhar um papel nele de alguma maneira? Estou curioso para saber se esse trabalho extra para extrair o mod pode ser um problema, em vez de simplesmente buscar a opção sem precisar fazer isso. Ao fazer a alteração de get_theme_mod()para get_option()a velocidade de todos os projetos, dobrou, em média, no frontend e no Customizer. Essa foi a única alteração feita em um esforço para isolá-lo de quaisquer outros efeitos colaterais.
— Ntg2 19/07/2014

Respostas:


19

A resposta é que sim, as funções theme_mod serão mais lentas, mas não significativamente, e os benefícios superam as diferenças.

Mods de tema são armazenados como opções. Portanto, em essência, as funções theme_mod são wrappers das funções de opções.

Primeiro, entenda que as configurações de theme_mod são armazenadas como uma matriz em uma única opção, com o nome do tema específico. Então, se eu fizer isso:

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

Então, o que eu realmente recebo no banco de dados é uma única linha de opções com o nome theme_mods_themename que contém uma matriz serializada com ('aaa' => 123, 'bbb' => 456).

Agora, get_theme_modserá mais lento porque na verdade está fazendo duas get_optionchamadas. Primeiro, ele recebe o nome do tema. Então, obtém a theme_mods_themenameopção. Então, aí está uma perda de velocidade de 50%. O restante do trabalho realizado está principalmente em filtros, pois há uma chamada extra, mas a menos que você tenha algo nesse filtro, isso é insignificante.

Observe que o sistema de opções armazena dados recuperados no cache do objeto, portanto, não faz várias chamadas ao banco de dados aqui. Somente o primeiro uso resulta em uma ocorrência no banco de dados.

O processo set_theme_modserá um pouco mais lento porque ele faz as mesmas duas chamadas de opções de obtenção, depois faz outra get_optionchamada para obter o nome do tema novamente e o mesmo ocorre update_optioncom o conjunto completo de opções agora alteradas. Isso causa uma atualização do banco de dados e o fato de estar enviando muito mais dados pode realmente ser a causa de uma desaceleração perceptível. Atualizar alguns bytes é mais rápido que atualizar uma linha maior. Mas não tanto quanto você notaria, normalmente. A menos que você tenha muitas configurações ...

As funções de modificação do tema provavelmente estão sujeitas à otimização geral, certamente, mas, no entanto, você ainda deve usá-las em vez de get_option e isso porque os temas filhos.

O problema com o uso de linhas de opções diretamente é que você as está usando diretamente e usando nomes de chave específicos para suas configurações.

Se eu tiver um tema chamado "AAA" e criar um tema filho chamado "BBB" para uso em outro site, meu tema "AAA" poderá usar uma opção chamada "exemplo". Quando eu atualizar um site e ele atualizar minha opção, a mesma opção será aplicada agora ao meu tema filho. E se eu não quisesse isso? E se eu quisesse que o tema filho usasse um conjunto diferente de configurações de opções?

Os mods de tema, incluindo o nome do tema real (e não um valor codificado) como parte da chave, garantem que cada "tema" no site use seu próprio conjunto de configurações. Eu posso alternar e as configurações não são transferidas entre elas, elas permanecem como eu as defini. Mais simples, mais óbvio, mais intuitivo.

E se alguma futura mudança ou plug-in principal modificar como o theme_mods funciona, você obterá automaticamente os benefícios sem alterações. Os invólucros sempre serão mais lentos, isso é inevitável, é a natureza dos invólucros. No entanto, você ainda está escrevendo código PHP, não linguagem de máquina. Usamos wrappers como esse para simplificar as coisas e separar a funcionalidade. Os temas não precisam saber, nem se importar, como suas opções são armazenadas no banco de dados ou como a nomeação funciona. As funções theme_mod fornecem uma solução mais simples e limpa.


3

get_theme_modé apenas um invólucro get_option. Em teoria, por ser outra camada de abstração, ele funcionará mais lentamente, mas na prática a diferença não deve ser grande o suficiente para ser notada por um humano.

As diferenças de velocidade reais podem ser causadas se você tiver algum código lento conectado aos ganchos theme_mod.


1

Poderia haver algo acontecendo no Customizer? Estou vendo a mesma coisa que o OP aqui.

Posso confirmar que, com cerca de 30 opções, o tempo de carregamento do Customizer caiu de cerca de 3s para cerca de 0,5s ao mudar para get_optionmais deget_theme_mod

Chamando os métodos diretamente, vejo uma diferença de 2ms.

Resultado dos testes ( https://gist.github.com/anonymous/d98a46d00d52d40e7dec )

Pode não ser perceptível quando você compara as APIs diretamente, mas deve haver algo com a forma como elas são utilizadas no Customizer.


1

Você pode testar o tempo de get_option(100 iterações) usando este código (inserido functions.phpou em algum 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;
}   




Outros pensamentos

Eu não sei, se faz alguma diferença (talvez os desenvolvedores do Wordpress o conheçam melhor), mas pensei que, se um site tem ALTO tráfego e, em cada carregamento de página, ele precisa ter centenas de opções, e se eu entrar? muitas opções em um get_option? como isso:

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

então :

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

isso tornará um site um pouco mais rápido?


2
É exatamente isso que o get_theme_mod já faz. Todos os mods de tema já estão associados a uma única opção. Sempre que você chama get_theme_mod, ele faz duas chamadas ao banco de dados na primeira vez e zero depois.
— Otto

0

TL; DR: Se você é um desenvolvedor de temas, deve usar get_theme_mod

Resposta completa:

Se você tiver 100 chamadas get_option, serão necessárias 100 consultas no seu banco de dados.

Se você tiver 100 chamadas get_theme_mod, serão necessárias apenas 1 consulta no seu banco de dados.

Por quê? Como todos os mods de tema são armazenados em uma única linha do banco de dados e serão chamados apenas um, enquanto cada opção é uma linha e 100 chamadas get_option resultam em 100 consultas ao banco de dados e, é claro, torna o site mais lento.

Se o seu tema tiver muitas opções, use get_theme_mod para reduzir significativamente o número da sua consulta no banco de dados.

Você pode verificar o desempenho e o número de consultas usando o plug-in do Monitor de consultas

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.