get_option () vs get_theme_mod (): Dlaczego jeden jest wolniejszy?

17

Od get_theme_mod()jakiegoś czasu korzystam z różnych moich projektów. Zdecydowałem się skorzystać z interfejsu API dostosowywania motywu w WordPress v3.4, gdy był dostępny, ponieważ uważałem, że jest to niezbędne narzędzie dla moich klientów.

Po jakimś czasie zacząłem zauważać, że moje strony czują się trochę bardziej powolne niż zwykle, a w szczególności Customizer ładował się dość długo. Dzięki wielu próbom i błędom podczas dochodzenia postanowiłem spróbować zrezygnować z typerejestracji moich ustawień (tj. $wp_customize->add_setting()) Od theme_moddo option.

Raz to zrobiłem i zamieniłem wszystkie moje get_theme_mod()połączenia zget_option() , zauważyłem bardzo znaczny wzrost prędkości przy użyciu tego drugiego zestawu, w przeciwieństwie do pierwszego na frontend, a zwłaszcza w Customizerze na backend. Przyglądałem się rdzeniu WordPress, próbując znaleźć odpowiedź na pytanie, dlaczego tak jest, ale nie wydaje mi się, aby rozpoznać, co jest szczególnym zawieszeniem w tym scenariuszu.

Wszelkie spostrzeżenia, jakie społeczność może mieć w odniesieniu do get_option()osiągania wyników znacznie szybciej niż get_theme_mod()byłoby to bardzo mile widziane.

ntg2
źródło
1
Jeśli spojrzysz /wp-includesna to, option.phpgdzie get_option()jest zdefiniowane, i theme.phpgdzie get_theme_mod()jest zdefiniowane, możesz zobaczyć, że ten ostatni tak naprawdę nazywa get_option()siebie, działając jako jego rozszerzenie, które stosuje również wszelkie niezbędne filtry. Może wyjaśnić, dlaczego jest wolniejszy.
Jody Heavener
1
Jody, myślałem, że sam, ale wydaje mi się, że po prostu odwołanie się get_option()i zastosowanie niektórych filtrów nie powinno spowolnić tak znacząco, jak było. Z pewnością świetny punkt wyjścia, ale zastanawiam się, czy nie ma tu nic innego.
ntg2
3
Nie ma powodu, by istniała jakakolwiek różnica prędkości, więc podejrzewam, że coś innego powoduje twoje postrzegane różnice. Mody motywu są przechowywane jako same opcje.
Otto
Czy proces serializacji / odserializacji przy pobieraniu indywidualnego modu może w jakiś sposób odegrać w tym rolę? Jestem ciekawy, czy ta dodatkowa praca polegająca na wyodrębnieniu modu może być zawieszeniem, a nie tylko pobieraniem opcji bez potrzeby robienia tego. Dokonując zmiany od get_theme_mod()do get_option()prędkości wszystkich projektów podwojeniu średnio zarówno nakładka aw Customizer. To była jedyna zmiana, której dokonano w celu odizolowania jej od jakichkolwiek innych skutków ubocznych.
ntg2

Odpowiedzi:

19

Odpowiedź brzmi: tak, funkcje theme_mod będą działały wolniej, ale nie znacząco, a korzyści przeważają nad różnicami.

Mody motywów są przechowywane jako opcje. Zasadniczo funkcje theme_mod otaczają funkcje opcji.

Najpierw zrozum, że ustawienia theme_mod są przechowywane jako tablica w jednej opcji, przypisanej do konkretnej nazwy motywu. Więc jeśli to zrobię:

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

Zatem to, co faktycznie otrzymuję w bazie danych, to pojedynczy wiersz opcji o nazwie theme_mods_themename, który zawiera szeregowaną tablicę z ('aaa' => 123, 'bbb' => 456).

Teraz get_theme_modbędzie wolniejszy, ponieważ w rzeczywistości wykonuje dwa get_optionpołączenia. Najpierw dostaje nazwę motywu. Potem dostajetheme_mods_themename opcję. A więc tutaj jest to 50% utrata prędkości. Reszta pracy polega głównie na filtrach, ponieważ istnieje dodatkowe wywołanie filtru, ale jeśli nie masz czegoś w tym filtrze, jest to trochę nieistotne.

Zauważ, że system opcji przechowuje pobrane dane w pamięci podręcznej obiektów, więc nie wykonuje tutaj wielu wywołań bazy danych. Tylko pierwsze użycie powoduje trafienie do bazy danych.

set_theme_modBędzie nieco wolniejszy, ponieważ to sprawia, że te same dwa dostać opcji połączeń, to ma inną get_optionrozmowę ponownie uzyskać nazwę tematu, a następnie robi update_optionz pełnym zestawem teraz zmienionych opcji. Powoduje to aktualizację bazy danych, a fakt, że wysyła znacznie więcej danych, może rzeczywiście być przyczyną zauważalnego spowolnienia. Aktualizacja kilku bajtów jest szybsza niż aktualizacja większego wiersza. Ale zwykle nie tak, jak można to zauważyć. Chyba że masz mnóstwo ustawień ...

Z pewnością funkcje modów motywów prawdopodobnie wymagają ogólnej optymalizacji, ale mimo to powinieneś ich używać zamiast get_option i dlatego, że motywy potomne.

Problem z bezpośrednim używaniem wierszy opcji polega na tym, że używasz ich bezpośrednio i używasz określonych nazw kluczy dla swoich ustawień.

Jeśli mam motyw o nazwie „AAA” i utworzę z niego motyw podrzędny o nazwie „BBB” do użytku w innej witrynie, to mój motyw „AAA” może użyć opcji o nazwie „przykład”. Kiedy zaktualizuję jedną witrynę i zaktualizuje ona moją opcję, wówczas ta sama opcja będzie miała zastosowanie do motywu podrzędnego. Co jeśli nie chcę tego robić? Co jeśli chciałbym, aby motyw potomny używał innego zestawu ustawień opcji?

Mody motywów, włączając rzeczywistą nazwę motywu (a nie wartość zapisaną na stałe) jako część klucza, zapewniają, że każdy „motyw” na stronie używa własnego zestawu ustawień. Mogę przełączać się między nimi, a ustawienia nie są przenoszone między nimi, pozostają one tak, jak je ustawiłem. Prostsze, bardziej oczywiste, bardziej intuicyjne.

A jeśli jakaś przyszła zmiana rdzenia lub wtyczka zmodyfikuje sposób działania theme_mods, to automatycznie uzyskasz korzyści bez żadnych zmian. Owijarki zawsze będą wolniejsze, co jest nieuniknione, taka jest natura owijarek. Niemniej jednak nadal piszesz kod PHP, a nie język maszynowy. Używamy takich opakowań, aby uprościć rzeczy i oddzielić funkcjonalność. Motywy nie powinny wiedzieć ani dbać o to, jak ich opcje są przechowywane w bazie danych ani jak działa nazewnictwo. Funkcje theme_mod zapewniają prostsze rozwiązanie, które jest czystsze.

Otto
źródło
3

get_theme_modto tylko opakowanie get_option. Teoretycznie, ponieważ jest to kolejna warstwa abstrakcji, będzie działać wolniej, ale w praktyce różnica nie powinna być na tyle duża, aby człowiek mógł ją zauważyć.

Rzeczywiste różnice prędkości mogą być spowodowane, jeśli na hakach theme_mod znajduje się wolny kod.

Mark Kaplun
źródło
1

Czy zatem może się coś wydarzyć w programie Customizer? Widzę tutaj to samo, co OP.

Potwierdzam, że przy około 30 opcjach mój czas ładowania Customizera spadł z około 3 s do około 5 s po przełączeniu get_optionnaget_theme_mod

Bezpośrednie wywołanie metod widzę różnicę 2 ms.

Wyniki testu ( https://gist.github.com/anonymous/d98a46d00d52d40e7dec )

Może nie być zauważalne przy bezpośrednim porównywaniu interfejsów API, ale musi być coś w tym, jak są one wykorzystywane w programie Customizer.

VykRevler
źródło
1

Można TEST CZASU o get_option(100 iteracji) przy użyciu tego kodu (umieścić w functions.phplub gdzieś):

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




Kolejne myśli

Nie wiem, czy to robi różnicę (może programiści Wordpress znają to lepiej), ale pomyślałem, że jeśli witryna ma duży ruch i przy każdym ładowaniu strony, musi uzyskać setki opcji, a co jeśli dołączę wiele opcji w jednym get_option? lubię to:

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

następnie :

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

czy to sprawi, że strona będzie trochę szybsza?

T.Todua
źródło
2
Właśnie to robi już get_theme_mod. Wszystkie mody motywu są już połączone w jedną opcję. Ilekroć wywołujesz get_theme_mod, za pierwszym razem wykonuje dwa wywołania bazy danych, a następnie zeruje wywołania bazy danych.
Otto
0

TL; DR: Jeśli jesteś programistą motywów, powinieneś użyć get_theme_mod

Pełna odpowiedź:

Jeśli masz 100 wywołań get_option, potrzeba 100 zapytań do bazy danych.

Jeśli masz 100 wywołań get_theme_mod, do bazy danych wystarczy tylko 1 zapytanie.

Dlaczego? Ponieważ wszystkie mody motywu są przechowywane w jednym wierszu bazy danych i będą nazywane tylko jednym, podczas gdy każda opcja jest wierszem, a 100 wywołań get_option spowoduje 100 zapytań do bazy danych i oczywiście spowolni działanie witryny.

Jeśli Twój motyw ma wiele opcji, użyj get_theme_mod znacznie zmniejszy liczbę zapytań do bazy danych.

Możesz sprawdzić wydajność i liczbę zapytań za pomocą wtyczki Query Monitor

Tran Cuong
źródło