get_theme_mod()
已有一段时间了。我决定在WordPress v3.4中使用主题自定义API,因为我觉得这是我的客户不可缺少的工具。一段时间后,我开始注意到我的网站感觉比平时慢了很多,尤其是Customizer的加载时间很长。经过大量的反复试验,我决定在将设置(即
type
)从$wp_customize->add_setting()
注册到theme_mod
时尝试切换出option
。一旦这样做,就换掉了所有
get_theme_mod()
调用get_option()
时,我注意到使用后一种设置的速度大大提高,与前端(尤其是后端的Customizer)相比,前者提高了速度。我一直在研究WordPress核心,以试图找出答案,但似乎无法识别这种情况下的特殊问题。任何见解非常感谢社区对于
get_option()
的执行要比get_theme_mod()
的执行速度快得多。#1 楼
答案是肯定的,theme_mod函数将变慢,但不会明显变慢,其好处大于差异。主题mods作为选项存储。因此,本质上,theme_mod函数是options函数的包装。因此,如果我这样做: aaa'=> 123,'bbb'=> 456)。
现在,
get_theme_mod
会变慢,因为它实际上正在进行两次get_option
调用。首先,它获得主题的名称。然后,它将获得theme_mods_themename
选项。因此,有50%的速度损失。剩下的工作大部分都在过滤器上,因为有一个额外的过滤器调用,但是除非您对该过滤器有任何要求,否则这是微不足道的。 请注意,选项系统将检索到的数据存储在对象高速缓存中,因此此处不会进行多个数据库调用。只有第一次使用会导致数据库命中。
set_theme_mod
会稍慢一些,因为它使这两个get选项调用相同,然后又进行另一个get_option
调用以再次获取主题名称,然后update_option
是否带有整套现已更改的选项。这会导致数据库更新,并且它发送大量数据的事实确实可能导致显着的速度下降。更新几个字节比更新较大的行更快。但通常不会如您所愿。除非您有很多设置的全部... 主题mod函数可能应该从总体上进行优化,但是,但是仍然应该使用它们而不是get_option等,因为子主题。
直接使用选项行的问题在于,您直接使用它们并为设置使用特定的键名。
如果我有一个名为“ AAA”的主题,并且将其子主题为“ BBB”用于其他站点,那么我的“ AAA”主题可能会使用一个名为“ example”的选项。当我更新一个站点并更新了我的选项时,该选项现在将应用于我的子主题。如果我不想这样做怎么办?如果我希望子主题使用一组不同的选项设置怎么办?
主题模块,通过将实际主题名称(而不是硬编码值)作为键的一部分包括在内,可以确保站点上的每个“主题”都使用自己的一套设置。我可以来回切换,并且设置不会在它们之间转移,它们仍然是我的设置方式。更简单,更明显,更直观。
如果将来的某些核心更改或插件修改了theme_mods的工作方式,那么您将无需任何更改即可自动受益。包装器总是会变慢,这是不可避免的,这是包装器的本质。但是,您仍在编写PHP代码,而不是机器语言。我们使用这样的包装器来简化事情并分离功能。主题无需知道或关心其选项如何存储在数据库中或命名如何工作。 theme_mod函数提供了更简单,更干净的解决方案。
#2 楼
get_theme_mod
只是get_option
的包装。从理论上讲,由于它是另一层抽象,因此它的工作速度会较慢,但实际上,这种差异不应太大,以至于人类无法察觉。钩在theme_mod钩上。#3 楼
定制器中可能会发生什么吗?我在这里看到的是与OP相同的东西。我可以确认,通过大约30个选项,Customizer的加载时间从3s左右下降到了通过
get_option
切换到get_theme_mod
时的大约0.5s 直接调用方法,我发现有2ms的差异。
(https://gist.github.com/anonymous/d98a46d00d52d40e7dec)
直接比较API时可能并不明显,但是必须与它们在Customizer中的使用方式有关。
#4 楼
您可以使用以下代码(放入get_option
或其他地方)测试functions.php
(100次迭代)的时间: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'];
................
这会使网站速度更快吗?
评论
这正是get_theme_mod已经完成的工作。所有主题模组都已加入一个选项。每当您调用get_theme_mod时,它将第一次进行两次数据库调用,之后进行零次数据库调用。
–奥托
16年9月16日在22:13
#5 楼
TL; DR:如果您是主题开发人员,则应使用get_theme_mod完整答案:
如果您有100个get_option调用,则它将对数据库进行100个查询。
如果您有100次get_theme_mod调用,则只需对数据库查询1次。
为什么?因为所有主题mod都存储在一个数据库行中,并且只能被调用,而每个选项都是一行,并且100次get_option调用将导致100次数据库查询,当然,这会降低您的网站速度。
如果您的主题有很多选项,请使用get_theme_mod将大大减少查询到数据库的次数。
您可以通过Query Monitor插件检查性能和查询次数
评论
这有点不正确。 get_theme_mod函数使用get_theme_mods-developer.wordpress.org/reference/functions/get_theme_mods-实际上运行2个get_option函数。因此100次get_theme_mod调用实际上向数据库发出了2个请求;)
– WPExplorer
20-4-14在22:58
评论
如果在/ wp-includes中查看定义了get_option()的option.php和在定义了get_theme_mod()的theme.php中,您会看到后者实际上调用了get_option()本身,作为扩展其中还应用了任何必要的过滤器。可以解释为什么它变慢。乔迪,我以为是我自己,但是感觉就像简单地引用get_option()并应用一些过滤器一样,不应使它的速度变慢。当然是一个很好的起点,但我想知道这里是否还有其他内容。
那里没有任何速度差异的原因,所以我怀疑其他原因导致了您的感知差异。主题模块本身存储为选项。
在获取单个mod时,序列化/反序列化过程可能以某种方式参与其中吗?我很好奇,是否可能需要额外的提取mod的工作而不是简单地获取选项而不需要这样做而导致的挂断。从get_theme_mod()更改为get_option()时,前端和定制程序中所有项目的速度平均都翻了一番。这是唯一旨在将其与其他副作用区分开的更改。