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.

ntg2
fonte
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.

Otto
fonte
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.

Mark Kaplun
fonte
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.

VykRevler
fonte
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?

T.Todua
fonte
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

Tran Cuong
fonte