get_option () vs get_theme_mod (): Perché uno è più lento?


17

Sto usando get_theme_mod()da tempo in vari miei progetti. Ho deciso di sfruttare l'API per la personalizzazione dei temi in WordPress v3.4 una volta disponibile perché ritenevo fosse uno strumento indispensabile per i miei clienti.

Dopo un po 'di tempo, ho iniziato a notare che i miei siti si sentivano un po' più lenti del solito, e il Customizer in particolare impiegava molto tempo a caricarsi. Attraverso un sacco di tentativi ed errori durante la mia indagine, ho deciso di provare a cambiare typequando registrando le mie impostazioni (cioè $wp_customize->add_setting()) da theme_moda option.

Una volta che ho fatto questo e ho scambiato tutte le mie get_theme_mod()chiamate get_option(), ho notato un aumento molto significativo della velocità usando quest'ultima impostazione rispetto alla prima sul frontend e soprattutto nel Customizer sul backend. Ho cercato nel core di WordPress nel tentativo di cercare di trovare una risposta al perché, ma non riesco a discernere quale sia il particolare blocco in questo scenario.

Eventuali approfondimenti che la community potrebbe avere in merito a get_option()prestazioni significativamente più veloci di quanto get_theme_mod()sarebbe molto apprezzato.


1
Se dai un'occhiata /wp-includesa option.phpdove get_option()è definito e a theme.phpdove get_theme_mod()è definito, puoi vedere che quest'ultimo si chiama effettivamente get_option(), agendo come un'estensione di esso che applica anche tutti i filtri necessari. Potrebbe spiegare perché è più lento.
Jody Heavener,

1
Jody, l'ho pensato da solo, ma sembra che fare semplicemente riferimento get_option()e applicare alcuni filtri non dovrebbe rallentarlo in modo così significativo. Certamente un ottimo punto di partenza, ma mi chiedo se non ci sia qualcos'altro nelle opere qui.
ntg2

3
Non vi è alcun motivo per qualsiasi tipo di differenza di velocità lì, quindi sospetto che qualcos'altro stia causando le tue differenze percepite. Le mod del tema sono memorizzate come opzioni stesse.
Otto

Il processo di serializzazione / non serializzazione nel recupero della singola mod potrebbe avere un ruolo in essa in qualche modo? Sono curioso di sapere se quel lavoro extra per estrarre la mod potrebbe essere un problema piuttosto che semplicemente recuperare l'opzione senza che sia necessario farlo. Quando si apporta la modifica get_theme_mod()alla get_option()velocità di tutti i progetti, in media è raddoppiata sia nel frontend che nel Customizer. Questo è stato l'unico cambiamento che è stato fatto nel tentativo di isolarlo da altri effetti collaterali.
ntg2

Risposte:


19

La risposta è sì, le funzioni di theme_mod saranno più lente, ma non significative, e i benefici superano le differenze.

Le mod del tema sono memorizzate come opzioni. Quindi, in sostanza, le funzioni theme_mod sono involucri attorno alle funzioni delle opzioni.

Innanzitutto, capire che le impostazioni di theme_mod sono memorizzate come una matrice in un'unica opzione, codificata per il nome specifico del tema. Quindi, se lo faccio:

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

Quindi quello che ottengo effettivamente nel database è una singola riga di opzioni con il nome di theme_mods_themename che contiene un array serializzato con ('aaa' => 123, 'bbb' => 456).

Ora get_theme_modsarà più lento perché in realtà sta effettuando due get_optionchiamate. Innanzitutto, ottiene il nome del tema. Quindi, ottiene iltheme_mods_themename opzione. Quindi proprio lì c'è una perdita di velocità del 50%. Il resto del lavoro svolto risiede principalmente nei filtri, in quanto esiste una chiamata di filtro aggiuntiva, ma a meno che tu non abbia qualcosa su quel filtro, questo è un po 'insignificante.

Si noti che il sistema di opzioni archivia i dati recuperati nella cache degli oggetti, quindi non effettua più chiamate al database qui. Solo il primo utilizzo provoca un hit nel database.

Il set_theme_modsarà po 'più lento perché rende quegli stessi due chiamate opzioni GET, poi fa un'altra get_optionchiamata per ottenere di nuovo il nome del tema, e poi lo fa update_optioncon la serie completa di opzioni ora è cambiato. Ciò provoca un aggiornamento del database e il fatto che stia inviando molti più dati può effettivamente essere la causa di un notevole rallentamento. L'aggiornamento di pochi byte è più rapido dell'aggiornamento di una riga più grande. Ma non tanto quanto noteresti, di solito. A meno che tu non abbia un sacco di impostazioni ...

Le funzioni di modifica del tema sono probabilmente dovute all'ottimizzazione complessiva, certamente, ma tuttavia dovresti comunque usarle al posto di get_option e perché temi figlio.

Il problema con l'utilizzo diretto delle righe delle opzioni è che le stai usando direttamente e usando nomi chiave specifici per le tue impostazioni.

Se ho un tema chiamato "AAA" e ne creo un tema figlio chiamato "BBB" da utilizzare su un altro sito, il mio tema "AAA" potrebbe utilizzare un'opzione denominata "esempio". Quando aggiorno un sito e aggiorna la mia opzione, la stessa opzione verrà ora applicata al tema di mio figlio. E se non volessi che lo facesse? E se volessi che il tema figlio usasse un diverso set di impostazioni delle opzioni?

Le mod del tema, includendo il nome del tema effettivo (e non un valore codificato) come parte della chiave assicurano che ogni "tema" sul sito utilizzi il proprio set di impostazioni. Posso passare avanti e indietro e le impostazioni non si trasferiscono tra loro, rimangono come le ho impostate. Più semplice, più ovvio, più intuitivo.

E se qualche cambiamento o plug-in futuro modificherà il modo in cui theme_mods funzionerà, allora otterrai automaticamente i vantaggi di questo senza alcuna modifica. Gli involucri saranno sempre più lenti, questo è inevitabile, è la natura degli involucri. Tuttavia, stai ancora scrivendo il codice PHP, non il linguaggio macchina. Utilizziamo involucri come questo per semplificare le cose e separare le funzionalità. I temi non dovrebbero avere bisogno di sapere o preoccuparsi di come le loro opzioni sono archiviate nel database o di come funziona la denominazione. Le funzioni theme_mod forniscono una soluzione più semplice che è più pulita.


3

get_theme_modè solo un involucro in giro get_option. In teoria, poiché è un altro strato di astrazione, funzionerà più lentamente, ma in pratica la differenza non dovrebbe essere abbastanza grande da essere notata da un essere umano.

Le effettive differenze di velocità possono essere causate se si dispone di un codice lento agganciato agli hook theme_mod.


1

Allora potrebbe succedere qualcosa in Customizer? Sto vedendo la stessa cosa dell'OP qui.

Posso confermare che con circa 30 opzioni il mio tempo di caricamento del Customizer è sceso da circa 3 secondi a circa 0,5 secondi quando si passa a get_optionoverget_theme_mod

Chiamando direttamente i metodi vedo una differenza di 2ms.

risultati del test ( https://gist.github.com/anonymous/d98a46d00d52d40e7dec )

Potrebbe non essere evidente quando si confrontano direttamente le API, ma deve esserci qualcosa con il modo in cui vengono utilizzate in Customizer.


1

Puoi PROVARE IL TEMPO di get_option(100 iterazioni) usando questo codice (inserito functions.phpo da qualche parte):

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




Un altro pensiero

Non so, se fa la differenza (forse gli sviluppatori di Wordpress lo sanno meglio), ma ho pensato che se un sito Web ha un traffico ELEVATO, e su ogni caricamento di pagina, ha bisogno di ottenere centinaia di opzioni, e se mi unissi molte opzioni in una get_option? come questo:

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

poi :

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

questo renderà un sito un po 'più veloce?


2
Questo è esattamente ciò che get_theme_mod fa già. Tutte le mod del tema sono già unite in un'unica opzione. Ogni volta che chiami get_theme_mod, effettua la prima volta due chiamate al database e successivamente zero chiamate al database.
Otto,

0

TL; DR: se sei uno sviluppatore di temi, dovresti usare get_theme_mod

Risposta completa:

Se hai 100 chiamate get_option, ci vogliono 100 query nel tuo database.

Se hai 100 chiamate get_theme_mod, ci vuole solo 1 query nel tuo database.

Perché? Poiché tutte le mod del tema sono memorizzate in una singola riga del database e verranno chiamate solo una, mentre ogni opzione è una riga e 100 chiamate get_option comporteranno 100 query del database e, naturalmente, rallenta il tuo sito.

Se il tuo tema ha molte opzioni, usare get_theme_mod ridurrà significativamente il numero di query nel database.

È possibile controllare le prestazioni e il numero di query dal plug-in Monitoraggio query

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.