get_option () vs get_theme_mod (): Warum ist man langsamer?

17

Ich habe get_theme_mod()für einige Zeit in verschiedenen Projekten von mir verwendet. Ich entschied mich, die Theme Customization API in WordPress v3.4 zu nutzen, sobald sie verfügbar war, da ich der Meinung war, dass sie für meine Kunden ein unverzichtbares Werkzeug ist.

Nach einiger Zeit bemerkte ich, dass sich meine Websites etwas träger anfühlten als gewöhnlich, und insbesondere der Customizer brauchte ziemlich lange, um geladen zu werden. Durch viele Versuche und Irrtümer während meiner Untersuchung habe ich mich entschlossen, typebeim Registrieren meiner Einstellungen (dh $wp_customize->add_setting()) von theme_modauf umzuschalten option.

Nachdem ich dies getan und alle meine get_theme_mod()Anrufe an getauscht hatte, get_option()bemerkte ich eine erhebliche Geschwindigkeitssteigerung bei Verwendung des letzteren Setups im Gegensatz zum ersteren auf dem Frontend und insbesondere im Customizer auf dem Backend. Ich habe den WordPress-Kern durchgesehen, um herauszufinden, warum dies so ist, kann aber anscheinend nicht erkennen, was der bestimmte Absturz in diesem Szenario ist.

Alle Erkenntnisse, die die Community möglicherweise im Hinblick auf get_option()eine deutlich schnellere Leistung hat get_theme_mod(), werden sehr geschätzt.

ntg2
quelle
1
Wenn Sie einen Blick in /wp-includesauf option.phpdem get_option()festgelegt ist, und bei theme.phpdenen get_theme_mod()festgelegt ist, können Sie sehen , dass diese tatsächlich nennt get_option()sich, als eine Erweiterung davon handeln , die auch alle notwendigen Filter gilt. Könnte erklären, warum es langsamer ist.
Jody Heavener
1
Jody, dachte ich mir, aber es fühlt sich an, als würde das einfache Referenzieren get_option()und Anwenden einiger Filter die Geschwindigkeit nicht so stark verringern, wie es war. Sicher ein guter Ausgangspunkt, aber ich frage mich, ob hier nicht noch etwas in Arbeit ist.
NTG2
3
Da es dort keinen Grund für Geschwindigkeitsunterschiede gibt, vermute ich, dass etwas anderes Ihre wahrgenommenen Unterschiede verursacht. Theme Mods werden als Optionen selbst gespeichert.
Otto
Könnte der Serialisierungs- / Unserialisierungsprozess beim Abrufen der einzelnen Mods eine Rolle spielen? Ich bin neugierig, ob diese zusätzliche Arbeit zum Extrahieren des Mods ein Auflegen sein könnte, anstatt einfach die Option abzurufen, ohne dies zu tun. Beim Wechsel von get_theme_mod()auf get_option()die Geschwindigkeit aller Projekte verdoppelte sich im Schnitt sowohl im Frontend als auch im Customizer. Dies war die einzige Änderung, die vorgenommen wurde, um sie von anderen Nebenwirkungen zu isolieren.
NTG2

Antworten:

19

Die Antwort: Ja, die theme_mod-Funktionen sind langsamer, aber nicht wesentlich, und die Vorteile überwiegen die Unterschiede.

Theme-Mods werden als Optionen gespeichert. Die theme_mod-Funktionen sind also im Wesentlichen Wrapper um die options-Funktionen.

Verstehen Sie zunächst, dass theme_mod-Einstellungen als Array in einer einzelnen Option gespeichert werden, die auf den jeweiligen Themennamen festgelegt ist. Also, wenn ich das mache:

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

Was ich dann tatsächlich in der Datenbank bekomme, ist eine einzelne Optionszeile mit dem Namen theme_mods_themename, die ein serialisiertes Array mit ('aaa' => 123, 'bbb' => 456) enthält.

Jetzt get_theme_modwird langsamer, weil es tatsächlich zwei get_optionAnrufe macht. Zuerst wird der Name des Themas abgerufen. Dann bekommt es die theme_mods_themenameOption. Genau da ist also ein Geschwindigkeitsverlust von 50%. Der Rest der Arbeit besteht hauptsächlich aus Filtern, da es einen zusätzlichen Filteraufruf gibt. Wenn Sie jedoch nicht über einen Filter verfügen, ist dieser unbedeutend.

Beachten Sie, dass das Optionssystem abgerufene Daten im Objektcache speichert, sodass hier nicht mehrere Datenbankaufrufe ausgeführt werden. Nur die erste Verwendung führt zu einem Datenbank-Treffer.

Das set_theme_modwird etwas langsamer sein, weil es dieselben zwei get options-Aufrufe ausführt, dann einen weiteren get_optionAufruf ausführt, um den Themennamen erneut abzurufen, und dann update_optionmit dem vollständigen Satz der jetzt geänderten Optionen. Dies führt zu einer Datenbankaktualisierung, und die Tatsache, dass viel mehr Daten gesendet werden, kann in der Tat die Ursache für eine spürbare Verlangsamung sein. Das Aktualisieren einiger Bytes ist schneller als das Aktualisieren einer größeren Zeile. Aber normalerweise nicht so sehr, wie Sie bemerken würden. Es sei denn, Sie haben eine ganze Menge Einstellungen ...

Die Theme-Mod-Funktionen sind sicherlich insgesamt zu optimieren, aber Sie sollten sie trotzdem anstelle von get_option und solchen verwenden, die untergeordnete Themes sind.

Das Problem bei der direkten Verwendung von Optionszeilen besteht darin, dass Sie sie direkt verwenden und bestimmte Schlüsselnamen für Ihre Einstellungen verwenden.

Wenn ich ein Thema mit dem Namen "AAA" habe und ein untergeordnetes Thema mit dem Namen "BBB" für die Verwendung auf einer anderen Website erstelle, verwendet mein Thema "AAA" möglicherweise eine Option mit dem Namen "example". Wenn ich eine Site aktualisiere und meine Option aktualisiere, gilt dieselbe Option jetzt für mein untergeordnetes Thema. Was ist, wenn ich das nicht wollte? Was ist, wenn das untergeordnete Thema andere Optionseinstellungen verwenden soll?

Durch das Einfügen des eigentlichen Themennamens (und nicht eines fest codierten Werts) in den Schlüssel stellen Sie sicher, dass jedes "Thema" auf der Site seine eigenen Einstellungen verwendet. Ich kann hin und her wechseln und die Einstellungen werden nicht zwischen ihnen übertragen, sie bleiben so, wie ich sie eingestellt habe. Einfacher, offensichtlicher, intuitiver.

Und wenn eine zukünftige Kernänderung oder ein Plugin die Funktionsweise von theme_mods ändert, werden Sie automatisch die Vorteile davon erhalten, ohne Änderungen vorzunehmen. Wrapper werden immer langsamer, das ist unvermeidlich, es liegt in der Natur der Wrapper. Trotzdem schreiben Sie immer noch PHP-Code, nicht Maschinensprache. Wir verwenden solche Wrapper, um Dinge zu vereinfachen und Funktionen zu trennen. Themen sollten nicht wissen oder kümmern müssen, wie ihre Optionen in der Datenbank gespeichert sind oder wie die Benennung funktioniert. Die theme_mod-Funktionen bieten eine einfachere und sauberere Lösung.

Otto
quelle
3

get_theme_modist nur ein Wrapper herum get_option. Theoretisch funktioniert es langsamer, da es sich um eine weitere Abstraktionsebene handelt. In der Praxis sollte der Unterschied jedoch nicht groß genug sein, um von einem Menschen bemerkt zu werden.

Tatsächliche Geschwindigkeitsunterschiede können verursacht werden, wenn Sie einen langsamen Code für die theme_mod-Hooks haben.

Mark Kaplun
quelle
1

Könnte dann etwas im Customizer passieren? Ich sehe hier das Gleiche wie das OP.

Ich kann bestätigen, dass mit ungefähr 30 Optionen die Ladezeit meines Customizers von ungefähr 3 Sekunden auf ungefähr 0,5 Sekunden gesunken ist, wenn ich auf " get_optionOver" umgeschaltet habeget_theme_mod

Wenn ich die Methoden direkt aufrufe, sehe ich einen Unterschied von 2 ms.

Testergebnisse ( https://gist.github.com/anonymous/d98a46d00d52d40e7dec )

Wenn Sie die APIs direkt vergleichen, ist dies möglicherweise nicht erkennbar, aber es muss etwas damit zu tun haben, wie sie im Customizer verwendet werden.

VykRevler
quelle
1

Sie können DIE ZEIT TEST von get_option(100 Iterationen) mit diesem Code (put in functions.phpoder irgendwo):

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




Noch ein Gedanke

Ich weiß nicht, ob es einen Unterschied macht (vielleicht wissen Wordpress-Entwickler es besser), aber ich dachte, wenn eine Website hohen Traffic hat und bei jedem Seitenaufruf Hunderte von Optionen benötigt, was passiert, wenn ich beitrete viele Möglichkeiten in einer get_option? so was:

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

dann :

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

Wird dies eine Website etwas schneller machen?

T.Todua
quelle
2
Genau das macht get_theme_mod schon. Alle Theme Mods sind bereits zu einer Option zusammengefasst. Wann immer Sie get_theme_mod aufrufen, werden beim ersten Aufruf zwei Datenbankaufrufe und danach null Datenbankaufrufe ausgeführt.
Otto
0

TL; DR: Wenn Sie ein Theme-Entwickler sind, sollten Sie get_theme_mod verwenden

Vollständige Antwort:

Wenn Sie 100 get_option-Aufrufe haben, werden 100 Abfragen an Ihre Datenbank gesendet.

Wenn Sie 100 get_theme_mod-Aufrufe haben, wird nur 1 Abfrage an Ihre Datenbank gesendet.

Warum? Da alle Theme-Mods in einer einzigen Datenbankzeile gespeichert sind und nur eine aufgerufen werden, ist jede Option eine Zeile und 100 get_option-Aufrufe führen zu 100 Datenbankabfragen und verlangsamen natürlich Ihre Site.

Wenn in Ihrem Design viele Optionen verfügbar sind, wird durch Verwendung von get_theme_mod die Anzahl der Abfragen in der Datenbank erheblich reduziert.

Sie können die Leistung und die Anzahl der Abfragen mit dem Query Monitor Plugin überprüfen

Tran Cuong
quelle