作为 WordPress 6.0 版本的一部分,性能团队一直在努力提高术语查询(term queries)的性能。平均页面加载有许多术语查询,改进这些查询通常可以提高 WordPress 的性能。
注:本文所说的“术语”英文为 term,这里统称所有分类法(Taxonomy)的分类。比如文章的分类和标签,就属于其中一种术语范畴。
改进术语查询缓存
自 4.6 以来,运行的查询WP_Term_Query
已被缓存。WordPress 6.0 中改进了这些缓存的准备和处理方式。
移除缓存限制
在 WordPress 6.0 之前,术语查询缓存仅限于使用持久对象缓存的 24 小时。这个限制现在被移除了,所以如果缓存没有失效,这意味着术语查询应该缓存更长的时间。对于不活动的站点或过夜,缓存应保持准备状态,这应该会提高站点性能。
有关详细信息,请参阅#54511。
词条查询缓存只缓存词条ID
术语查询缓存已更改,现在只缓存术语 ID,而不是缓存整个术语对象。这意味着存储在缓存中的值将小得多(就内存而言),并且不会填满会话或持久对象缓存中的内存。
一旦加载了术语的所有 ID,就会调用_prime_term_cache
函数。这会加载到尚未在缓存中的内存项中。如果术语已经在内存中,则不会再次加载它,这是一个性能优势。在平均页面加载中,可能会多次请求一个术语,例如标签存档页面。在页面加载的早期,get_term_by
, 将启动缓存项,而所有其他调用(例如get_the_terms
)将使项已在页面内存中启动。在大多数情况下,可使针对术语表运行的查询越来越少。
有关详细信息,请参阅#37189。
改进的术语查询缓存键生成
以前,具有相似缓存键的相似术语查询将导致在单个页面加载时运行两次基本相同的查询。因为现在所有查询都只获取词条 ID 并将其存储在缓存中(见上文),因此缓存完全相同。例如,您创建一个调用到get_terms
来请求所有类别并仅返回字段 slug。如果您执行相同的查询并仅请求名称,那么这将命中相同的缓存。
另一个改进是处理可以传递给WP_Term_Query
可能不明确的参数。像 slug 这样可以是字符串或数组的字段现在被转换为始终为数组,这意味着重用缓存的可能性更高,因为无论传递哪种类型的参数,缓存键都相同。
有关详细信息,请参阅#55352。
提高导航菜单项的性能
转换 wp_get_nav_menu_items 以使用分类查询
使用简单的分类查询代替了get_objects_in_term
函数的使用。此替换将两个查询的使用转换为使用一个简单查询来获取菜单项。这样可以为每个请求的菜单保存一个查询并增加一致性。
有关详细信息,请参阅#55372。
在 wp_get_nav_menu_items 中填充所有术语和文章缓存
wp_get_nav_menu_items
函数现在调用_prime_term_cache
和_prime_post_cache
链接到菜单项的所有对象。如果菜单包含类别和页面列表,则所有相关对象现在都在两个缓存调用中准备好(一个用于术语,一个用于文章)。这将减少对数据库和缓存的请求。
有关详细信息,请参阅#55428。
将 term_exists 转换为使用 get_terms
函数term_exists
现在已转换为使用get_terms
( WP_Term_Query
) 在内部替换原始未缓存的数据库查询。该函数是对数据库中的terms
表执行原始查询的最后一个位置之一。使用get_terms
功能有许多关键好处,包括:
- 与其他核心功能的一致性,如
get_term_by
- 过滤结果的能力。
- 缓存
get_terms
结果
term_exists
专为后端使用而设计,主要用于将数据写入term
表的核心功能。但是,一些主题和插件开发人员可以并且正在使用term_exists
,这会导致在站点的前端运行原始的不可缓存和不可过滤的查询。
现在term_exists
已缓存,自定义导入/迁移工具可能需要检查它们是否正确缓存了失效词条。如果您的导入代码正在使用诸如 wp_insert_term
之类的核心函数,则无需执行任何操作,因为核心会为您执行自己的缓存失效。但是,如果您手动将数据写入term
表中,则可能需要调用clean_term_cache
函数。
对于那些需要确保term_exists
获得未缓存结果的人,有两种方法可以做到这一点:
- 使用新的
term_exists_default_query_args
过滤器
$callback = function ( $args ) {
$args['cache_domain'] = microtime();
};
add_filter( 'term_exists_default_query_args', $callback );
$check = term_exists( 123, 'category' );
remove_filter( 'term_exists_default_query_args', $callback );
- 使用
wp_suspend_cache_invalidation
wp_suspend_cache_invalidation( true );
$check = term_exists( 123, 'category' );
wp_suspend_cache_invalidation( false );
有关详细信息,请参阅#36949。
为分类查询添加限制
WP_Tax_Query
类被用于WP_Query
来按术语限制查询。在幕后,WP_Tax_Query
使用WP_Term_Query
,这意味着WP_Tax_Query
将获得上面记录的缓存改进的好处。该WP_Tax_Query
运行将术语 slugs / 名称转换为要查询的术语 ID,现在添加了一个限制。此查询限制提高了查询的性能,并提高了现有缓存查询继续存在于对象缓存中的可能性。例如,标准标记存档调用get_term_by
并准备缓存。当它到达WP_Tax_Query
时,该查询正在从缓存中加载。这将删除每个标签存档页面的一个查询。
有关详细信息,请参阅#55360。
注:以上机器翻译,有些拗口,请见谅。会英文的可以看下官方文章。