我在我的各种项目中使用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()的执行速度快得多。

评论

如果在/ wp-includes中查看定义了get_option()的option.php和在定义了get_theme_mod()的theme.php中,您会看到后者实际上调用了get_option()本身,作为扩展其中还应用了任何必要的过滤器。可以解释为什么它变慢。

乔迪,我以为是我自己,但是感觉就像简单地引用get_option()并应用一些过滤器一样,不应使它的速度变慢。当然是一个很好的起点,但我想知道这里是否还有其他内容。

那里没有任何速度差异的原因,所以我怀疑其他原因导致了您的感知差异。主题模块本身存储为选项。

在获取单个mod时,序列化/反序列化过程可能以某种方式参与其中吗?我很好奇,是否可能需要额外的提取mod的工作而不是简单地获取选项而不需要这样做而导致的挂断。从get_theme_mod()更改为get_option()时,前端和定制程序中所有项目的速度平均都翻了一番。这是唯一旨在将其与其他副作用区分开的更改。

#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