kn007的个人博客
♥ You are here: > > > 解决后台评论编辑管理页面慢的问题

解决后台评论编辑管理页面慢的问题

by | 57 Comments


在前期文章《全新WordPress评论管理系统》,我提到了为何写这个插件,最主要的原因,还是因为后台评论编辑管理页面慢。想想显示20条评论要近6秒时间,这谁能忍。所以只能自己做一个轮子。

但作为一个爱折腾,愿解决实事的人,逃避不是我的风格(这句纯属胜利者装逼)。

我新建了Wordpress,使用原始主题,将现有主题的所有文章、评论、附件、类别移到这个新Wordpress。

发现后台评论编辑管理页面速度特别快,即便设置显示100条也0.11秒左右显示。

启用Memcached外部对象缓存,发现速度依然如旧,飞快。

这说明两种可能,我想到的两种:第一种主题问题,第二种WP升级遗留问题。

所以在新Wordpress启用了新主题,测试后台评论编辑管理页面,速度慢下来了,要5秒多。

因为主题模块化了,并且把功能分类后,归类到文件。

所以很好排除,二分法禁用这些模块,发现是Wordpress钩子模块出问题,其中只有几个是关于评论的。最终定位是一个“清除评论里的其他计数”的函数,hook对象是get_comments_number

add_filter('get_comments_number', 'comment_count', 0);
function comment_count( $count ) {
	global $id;
	$comments_by_id = get_comments('status=approve&post_id=' . $id);
	$comments_by_type = separate_comments($comments_by_id);
	return count($comments_by_type['comment']);
}

因为get_comments_number本身获取的是该文章的所有评论计数,而一篇文章的评论计数,不单只是评论,还有Trackbacks、Pingbacks,而评论还有已通过、待审核、垃圾评论等。

所以这个函数主要就是为了修复这一问题,因为我们一般只为了获取已通过审核的评论,其他都不要。

好,那么来看看这个函数,初看没什么大问题。但是不知从哪个版本开始,那个id参数回值是空。也就是说不知什么时候Wordpress不主动全局定义这个参数了。我看了下,貌似只在文章主循环会传递,其他留空。

这可就捅破了天了,因为id是空,那么post_id就是空了。

get_comments就会获取所有通过评论的数量,然后返回计数给get_comments_number,而后台评论编辑管理页面以get_comments_number得到的数量,请求这些评论的所有缓存,如果缓存不存在就创建。

这本来是好事,但因为一个微小的错误,加上我们后台是显示20条评论。也就是相当于要20次缓存的判断、建立等动作,虽然Wordpress会合并id后然后再去请求数据库,但对id却不去重,也就是数据库会返回20*通过评论总数量的请求,然后php再一一进行缓存判断,不存在的建立,这花费了大量时间(这是我猜测的,因为那一瞬间MySQL发送了大量数据,而php单进程也占用100%)。而显示越多评论,各应用压力就更大。

知道原因就好办了,直接查到Wordpress的get_comments_number原始函数,发现其过滤器为:

return apply_filters( 'get_comments_number', $count, $post_id );

也就是说他可以传递两个参数,其中就有我们需要的重要参数,$post_id

于是修改下“清除评论里的其他计数”函数,改成如下:

add_filter('get_comments_number', 'comment_count', 0, 2);
function comment_count( $count, $post_id ) {
	$comments_by_id = get_comments('status=approve&post_id=' . $post_id);
	$comments_by_type = separate_comments($comments_by_id);
	return count($comments_by_type['comment']);
}

如此,便解决了该问题。

目前设置显示100条评论,只要1/3秒,这速度能接受。用了这个函数慢0.2秒,能接受的。

Had 3 queries, using 14.30MB memory, page to load in 0.349 seconds

这个函数算是历史遗留函数,基本上旧版的大多数主题都会用到,比较实用。

我的主题一直继承这个函数,所以就出现这一问题。各位老哥们,还用这个函数,注意要脱坑啊。

原始作者已经不知是谁,但当时可能没考虑太多,又能用,写成这样已经不错了。

出现这种问题,主要还是升级遗留问题,没去更新这个函数(当然,也不会想到这个问题)。

不过好在发现并解决了。

而且刚刚的“清除评论里的其他计数”函数还不是最原始的模样,我留存中这个函数最原始的模样如下(爱收藏的命,这是3.3版本时的记录):

add_filter('get_comments_number', 'comment_count', 0);
function comment_count( $count ) {
	global $id;
	$comments = get_approved_comments($id);
	$comment_count = 0;
	foreach($comments as $comment){
		if($comment->comment_type == ""){
			$comment_count++;
		}
	}
	return $comment_count;
}

在Wordpress跟踪了下get_comments_number的原始函数,发现从2.9版本开始,开始传递两个参数,count和post_id,而在2.8.6还只传递一个参数,number。

也就是说可以看出当时那个写“清除评论里的其他计数”函数的作者,并不会利用和使用get_comments_number原始函数的第二个参数。

id什么时候没全局就不知道了,这个没追踪,太多依赖函数了。不管了。

转载请注明转自:kn007的个人博客的《解决后台评论编辑管理页面慢的问题

donate
有所帮助?

Comments

57 Comments立即评论
Loading...
  1. LV1回复

    不如把精力放在有意义的事情上 :roll:

    1. MOD回复
  2. 一如既往的支持折腾精神。

    1. MOD回复

      @郑永: 哈,是的~

  3. 我怎么没有发现有速度上的问题?

    1. MOD回复

      @土木坛子: 默认主题应该没什么问题。
      之前主要是因为后台 /wp-admin/edit-comments.php 慢,现在找到原因就不慢。
      前台的话一直不受影响,没什么问题。

  4. 还是新的评论系统快啊。
    另外,自己搭建评论系统,就经常出事情。后台查了,发现自己把Ghost的主题文件当成配置文件,塞进Supervisord的配置文件夹里了,评论系统直接宕机……

    1. MOD回复

      @云间守望: 哈哈哈

  5. 我一直玩不转WP,就撤了

    1. MOD回复

      @文栋说自媒体: 不折腾也差不多

  6. 哪里找得到插件开发教程嘛 :grin:

    1. MOD回复

      @helsing.lee: 还真不知道,我插件是先按照传统php写好,然后再移植到wordpress对接起来 :grin:

    2. MOD回复

      @helsing.lee: 我估计也就是我才这么奇葩的作法。

  7. 太技术了,真心看不懂 :o

    1. MOD回复

      @秦大叔: 谦虚了

  8. 不错,过来膜拜一下! :smile:

icon_wink.gificon_neutral.gificon_mad.gificon_twisted.gificon_smile.gificon_eek.gificon_sad.gificon_rolleyes.gificon_razz.gificon_redface.gificon_surprised.gificon_mrgreen.gificon_lol.gificon_idea.gificon_biggrin.gificon_evil.gificon_cry.gificon_cool.gificon_arrow.gificon_confused.gificon_question.gificon_exclaim.gif