get_option () против get_theme_mod (): почему один медленнее?

17

Я использовал в get_theme_mod()течение некоторого времени в различных моих проектах. Я решил воспользоваться API настройки темы в WordPress v3.4, как только он стал доступен, так как я чувствовал, что это необходимый инструмент для моих клиентов.

Через некоторое время я начал замечать, что мои сайты чувствовали себя немного более вялыми, чем обычно, и, в частности, настройщик загружался довольно долго. Из-за большого количества проб и ошибок во время моего исследования, я решил попробовать отключить typeпри регистрации мои настройки (т.е. $wp_customize->add_setting()) из theme_modв option.

Как только я сделал это и поменял все свои get_theme_mod()вызовы на get_option(), я заметил очень значительное увеличение скорости при использовании последней настройки в отличие от первой на внешнем интерфейсе и особенно в настройщике на внутреннем интерфейсе. Я просматривал ядро ​​WordPress, пытаясь найти ответ на вопрос, почему это так, но, похоже, не могу понять, что такое зависание в этом сценарии.

Любое понимание, которое сообщество может иметь в отношении get_option()выполнения значительно быстрее, чем get_theme_mod()было бы высоко ценится.

ntg2
источник
1
Если вы посмотрите /wp-includesна то, option.phpгде get_option()определено, и theme.phpгде get_theme_mod()определено, вы увидите, что последний фактически вызывает get_option()себя, действуя как его расширение, которое также применяет любые необходимые фильтры. Не могли бы объяснить, почему это медленнее.
Джоди Хивенер
1
Джоди, я думал, что сам, но это похоже на простую ссылку get_option()и применение некоторых фильтров, которые не должны замедлять его так значительно, как это было раньше. Конечно, отличная отправная точка, но мне интересно, нет ли здесь чего-то еще в работах.
ntg2
3
Там нет никаких причин для какой-либо разницы в скорости, поэтому я подозреваю, что что-то другое вызывает ваши предполагаемые различия. Тематические моды хранятся в виде самих опций.
Отто
Может ли процесс сериализации / десериализации при получении отдельного мода сыграть в этом какую-то роль? Мне любопытно, может ли эта дополнительная работа по извлечению мода быть зависанием, в отличие от простого извлечения опции без необходимости делать это. При внесении изменения от get_theme_mod()до get_option()скорости всех проектов в два раза в среднем на обоих веб - интерфейсе и в настройщика. Это было единственное изменение, которое было сделано в попытке изолировать его от любых других побочных эффектов.
ntg2

Ответы:

19

Ответ: да, функции theme_mod будут работать медленнее, но незначительно, а преимущества перевешивают различия.

Тематические моды хранятся в виде опций. Итак, по сути, функции theme_mod являются обертками для функций параметров.

Во-первых, следует понимать, что настройки theme_mod хранятся в виде массива в одной опции, привязанной к конкретному названию темы. Итак, если я сделаю это:

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

Тогда то, что я на самом деле получаю в базе данных, это одна строка опций с именем theme_mods_themename, которая содержит сериализованный массив с ('aaa' => 123, 'bbb' => 456) в нем.

Теперь get_theme_modбудет медленнее, потому что он на самом деле делает два get_optionзвонка. Во-первых, он получает название темы. Затем он получает theme_mods_themenameвозможность. Так что тут потеря скорости 50%. Остальная часть проделанной работы заключается в основном в фильтрах, в том, что есть дополнительный вызов фильтра, но если у вас нет чего-то в этом фильтре, это довольно незначительно.

Обратите внимание, что система опций сохраняет извлеченные данные в кеше объектов, поэтому здесь не нужно выполнять несколько вызовов базы данных. Только первое использование приводит к попаданию в базу данных.

Это set_theme_modбудет несколько медленнее, потому что он делает те же самые два вызова get options, затем делает еще один get_optionвызов, чтобы снова получить имя темы, а затем делает это update_optionс полным набором теперь измененных параметров. Это вызывает обновление базы данных, и тот факт, что она отправляет намного больше данных, действительно может быть причиной заметного замедления. Обновление нескольких байтов происходит быстрее, чем обновление строки большего размера. Но обычно не так много, как вы заметили. Если у вас нет чертовски много настроек ...

Функции мода темы, вероятно, должны быть оптимизированы в целом, но, тем не менее, вы все равно должны использовать их вместо get_option и так далее, потому что дочерние темы.

Проблема с использованием строк параметров напрямую заключается в том, что вы используете их напрямую и используете конкретные имена ключей для своих настроек.

Если у меня есть тема под названием «AAA» и я создаю дочернюю тему под названием «BBB» для использования на другом сайте, тогда моя тема «AAA» может использовать параметр с именем «example». Когда я обновляю один сайт, и он обновляет мой параметр, то этот же параметр теперь будет применяться к моей дочерней теме. Что если я не хочу этого делать? Что, если я хочу, чтобы дочерняя тема использовала другой набор параметров?

Тематические моды, включая фактическое название темы (а не жестко заданное значение) как часть ключа, гарантируют, что каждая «тема» на сайте использует свой собственный набор настроек. Я могу переключаться вперед и назад, и настройки не передаются между ними, они остаются такими, как я их установил. Проще, понятнее, понятнее.

И если какое-то будущее изменение ядра или плагин изменят работу theme_mods, то вы автоматически получите преимущества без каких-либо изменений. Обертки всегда будут медленнее, это неизбежно, это природа оберток. Тем не менее, вы все еще пишете код PHP, а не машинный язык. Мы используем такие обертки, чтобы упростить вещи и разделить функциональность. Темы не должны знать или заботиться о том, как их параметры хранятся в базе данных или как работает именование. Функции theme_mod обеспечивают более простое решение, которое чище.

эфирное масло
источник
3

get_theme_modэто просто обертка вокруг get_option. Теоретически, поскольку это еще один уровень абстракции, он будет работать медленнее, но на практике разница не должна быть достаточно большой, чтобы ее заметил человек.

Реальные различия в скорости могут быть вызваны, если у вас есть какой-то медленный код, подключенный к хукам theme_mod.

Марк Каплун
источник
1

Может ли что-то происходить в настройщике тогда? Я вижу то же самое, что и ОП здесь.

Я могу подтвердить, что примерно с 30 опциями время загрузки в настройщик уменьшилось с 3 до примерно 5 с при переключении на get_option болееget_theme_mod

Вызывая методы напрямую, я вижу разницу в 2 мс.

результаты теста ( https://gist.github.com/anonymous/d98a46d00d52d40e7dec )

Это может быть незаметно при непосредственном сравнении API, но должно быть что-то с тем, как они используются в Customizer.

VykRevler
источник
1

Вы можете проверить время из get_option(100 итераций) с помощью этого кода (поставить functions.phpили где - нибудь):

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




Другие мысли

Я не знаю, если это будет иметь значение (возможно, разработчики Wordpress знают это лучше), но я подумал, что если у сайта высокий трафик, и при каждой загрузке страницы ему нужно получить сотни вариантов, то что, если я присоединюсь? много вариантов в одном get_option? как это:

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

тогда :

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

это сделает сайт немного быстрее?

T.Todua
источник
2
Это именно то, что get_theme_mod уже делает. Все моды темы уже объединены в одну опцию. Каждый раз, когда вы вызываете get_theme_mod, он делает два вызова базы данных в первый раз, а затем - нулевые вызовы базы данных.
Отто
0

TL; DR: если вы разработчик темы, вы должны использовать get_theme_mod

Полный ответ:

Если у вас есть 100 вызовов get_option, он принимает 100 запросов к вашей базе данных.

Если у вас есть 100 вызовов get_theme_mod, это займет всего 1 запрос к вашей базе данных.

Почему? Поскольку все моды темы хранятся в одной строке базы данных и будут называться только одной, в то время как каждая опция является строкой, и 100 вызовов get_option приведут к 100 запросам к базе данных и, конечно, это замедлит работу вашего сайта.

Если ваша тема имеет много опций, использование get_theme_mod значительно уменьшит количество запросов к базе данных.

Вы можете проверить производительность и количество запросов с помощью плагина Query Monitor.

Тран Куонг
источник