WordPress 6.0 提升了分类模式的性能

2023-04-13 11:12:12 浏览数 (1)

WordPress 6.0 对性能提升还是做了很多工作的,比如昨天文章介绍的新增了批量添加、设置和删除一组缓存的函数,对分类模式下各种查询也进行提升。

分类查询缓存改进

从 WordPress 4.6 版开始,WP_Term_Query 的查询就可以缓存,WordPress 6.0 改进了这些缓存的准备和处理方式。

移除缓存过期事件

WordPress 6.0 之前,如果使用 Memcached 这类外部缓存,分类模式查询的缓存最长24小时,现在这个限制被移除了,所以如果缓存没有失效,那么分类模式查询就会被缓存更长的时间,这样会显著提高站点性能。

查询缓存只缓存 Term ID

分类模式查询的缓存修改成只缓存 Term ID 而不是整个 Term 对象,这样存储在缓存中的对象将会更加的小,如果使用 Memcached 这类外部缓存,可以更省空间。

因为只缓存 Term ID,那么下次从缓存中获取所有 ID 的时候,WordPress 会调用 _prime_term_cache 函数,检测对应 Term 是不是在缓存中,如果不在,它会一次把所有 Term 加载到缓存中,如果已经在了,则不会重复加载。

这些改进都会对性能的提升有好处,因为 WordPress 很多函数的调用都会多次请求一个 Term 的数据,比如标签页,就会一开始通过 get_term_by 函数准备好 Term 缓存,还有其他的函数比如 get_the_terms 也会在内存中准备好 Term 缓存,所以在大多数情况下,这些优化都会减少分类模式相关数据表的查询。

改进查询缓存 key 生成规则

如上所述,现在所有查询只获取 Term ID,所以很多相似的查询,它们缓存的内容都是相同的,比如使用 get_terms 去获取所有分类信息,第一次获取 slug 字段,第二次获取名称,两次查询应该会命中相同的缓存。

另外对传递给 WP_Term_Query 的查询参数的处理也进行了优化,比如 slug 字段可能是字符串,也可能是数组,现在统一转换成数组,这样无论你传递什么类型的参数,缓存的 keys 相同的可能性更高,缓存命中率也提高了。

提高导航菜单的性能

在获取导航菜单的 wp_get_nav_menu_items 函数中,首先使用简单的 taxonomy query 代替 get_objects_in_term 函数,这个替换首先可以把两次数据库查询降低到一次,这样每次获取菜单都能节省一次 SQL 请求,并且还能保持数据的一致性。

此外如果菜单中含有分类和文章的数据,wp_get_nav_menu_items 会改成使用 _prime_term_cache 和 _prime_post_cache 来准备 term 和 post 的缓存,这两个函数的使用会使得获取菜单的数据库请求变得更少,效率更高。

term_exists 使用 get_terms 处理

term_exists 函数内部从使用非缓存的数据库查询转换成使用 get_terms ( WP_Term_Query ) 来处理,这个函数是最后一个对 terms 数据库表执行原始数据库查询的函数,改用 get_terms 函数有下面这些好处:

  • 保持和其他核心函数一致,如 get_term_by
  • 支持对结果过滤的能力
  • get_terms 结果是缓存的

term_exists 本来适用于在写入数据库之前的数据重复性检测,然后这个函数被很多插件和主题开发者使用了,这样就造成了站点很多地方有未缓存和未过滤的查询结果。

现在 term_exists 改用 get_terms 处理之后,数据是缓存的,如果你还需要获取未缓存的结果,有两个方法:

  1. 使用  term_exists_default_query_args  filter
代码语言:javascript复制
$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 );
  1. wp_suspend_cache_invalidation
代码语言:javascript复制
wp_suspend_cache_invalidation( true );
$check = term_exists( 123, 'category' );
wp_suspend_cache_invalidation( false );

WordPress Taxonomy Cache Fix

但是经过测试,WordPress 6.0 升级还造成了 child_of 参数的失效,我写了一个小插件修复了该问题。

0 人点赞