重构WordPress以提高内存性能

时间:2011-02-25 作者:Roman Zenka

我仔细查看了Wordpress的内存消耗情况。在我的网站上,似乎为每个页面分配了20MB的RAM,只是为了为所有插件的运行准备一个舒适的环境。我这样策划:

没有一个地方需要优化,没有一个坏蛋会吃掉大部分内存。消耗量分布在许多php模块上。

我们如何让Wordpress在内存中只初始化一次环境,然后在每次点击时多次重用它?我不想让速度慢的PHP在每次用户点击时消耗20 MB的内存——即使在内存丰富的服务器上,完成所有这些工作也需要几秒钟的时间。您基本上需要可以重用的只读内存块。

而且为什么是20MB?有人能对此提供见解吗?

编辑:这是在我的开发机器上运行的Wordpress上的WinCacheGrind输出(比共享主机快得多)。正如您所看到的,仅仅生成主页的HTML就需要花费一秒钟的时间。通过共享主机来减缓这一速度,你就会遇到麻烦。我选择了占用大部分时间的方法。您将如何对此进行优化?

编辑:以下是来自的查询统计信息this fantastic functions.php profiling tool.

Load: 12 queries - 532ms - 19.1MB - 43 cache hits / 53
Query: 15 queries - 563ms - 19.0MB - 72 cache hits / 86
Display: 21 queries - 705ms - 19.2MB - 234 cache hits / 257
编辑:你想看一些肯定会吓到你的东西吗?在索引末尾插入这些行。php:


echo "<pre>\\n";
print_r(get_defined_vars());
echo "</pre>\\n";
我试图数一数当前帖子的正文存储在内存中的次数。我数了20个例子。然后我意识到PHP有引用计数,所以拷贝数量减少到只有三个:两个似乎在WP\\U查询中,一个在对象缓存中。我正在进一步调查。

这就是为什么我认为WordPress需要针对内存问题进行重构。您再也不能将其内存消耗归咎于其工作的复杂性。它只是做了一大堆错事。

编辑:经过一天的努力,我的发现如下:

1) 88%的内存来自require或include或include\\u once类型的调用:

2) php文件包含主要发生在服务请求的第一部分(毫不奇怪),这也是耗尽所有内存的地方:

3) 绘制发出请求期间正在执行的所有函数非常有趣。总共有12000多个电话。我抖动它们以使其更可见(水平轴基本上是堆栈的深度):

4) 我能想到的唯一前进的方法是尽量减少。包含php文件。如果我将函数按它们来自的文件进行拆分,您可以看到许多文件最多被命中一次或两次。我们需要一种方法,在不需要的时候跳过它们。例如,我的远程数据库备份插件被加载和注册,只是为了永远不用。以下是按文件名拆分的上述绘图:

我提供了一笔名副其实的奖金:)用于重构,这将导致我的博客内存占用减少30%或更多。

编辑:我安装了WP 3.1,这里是与旧版本的比较。

蓝色为WP 3.1,红色为3.0.4。新的WP速度更快,但占用更多内存。

以下是包含文件的列表。

这让我意识到“一应俱全的SEO包”消耗了多少内存——一种方法是只使用插件功能的一小部分来获得我想要的东西。而且,我自己的插件似乎很糟糕。

我想尝试条件加载,例如注释。php(我不允许在我的博客上发表评论)和其他几个网站。我删除了所有不推荐使用的代码。我修剪了KSE。php仅按需加载其全局表。我简化了l10n(不进行本地化),使其函数立即返回字符串,无需查找。我还远远没有达到我任意设定的30%的分数。

编辑:我下载并启用了带有默认设置(32MB操作码缓存)的APC。比较如下:

您可以看到,代码加载速度大大加快,代码占用的内存空间也更少(可能是因为我们只处理操作码,而不是原始源代码)。然而,内存消耗仍然相当高。

8 个回复
SO网友:Rarst

不值得这么麻烦。WordPress不会因为这样就占用大量内存。它消耗了大量内存,因为它在引擎盖下运行了大量功能。

使用静态缓存插件缓存结果(生成的页面)并提供服务要容易得多,效率也更高。这样,大多数访问者甚至不会碰到WP本身。

SO网友:scribu

这就是为什么我认为WordPress非常需要重写。您再也不能将其内存消耗归咎于其工作的复杂性。它只是做错了事情。

多么天真的结论啊。阅读Things You Should Never Do, Part I.

不过,感谢您提供的内存使用情况图表。

Much later edit: Autommatic发布了一个名为prefork 这似乎满足了您的要求:只在RAM中加载WordPress代码一次。

SO网友:Dougal Campbell

从WordPress 3.2开始,PHP 5.2将是最低要求。我认为,在我们的皮带下,核心部分可以开始重组,并使用具有自动加载的类。这将使我们避免加载一些代码块,除非它们实际上是需要的。例如,若页面视图中并没有嵌入或库,我们可能可以避免加载大量媒体代码。

然而,即使他们决定走这条路,我也会认为这是一个缓慢的演变(就像其他已经发生的幕后变革一样)。这将需要在大量文件和代码的位置上来回移动,这可能会破坏某些插件的向后兼容性。

部分问题(如果真的可以这样称呼的话)是,如果没有这种条件加载,核心框架无法提前知道生成内容视图需要或不需要哪些功能。因此,必须加载许多函数,以备不时之需。

SO网友:Otto

我们如何让Wordpress在内存中只初始化一次环境,然后在每次点击时多次重用它?

这叫做操作码缓存。

http://en.wikipedia.org/wiki/PHP_accelerator

SO网友:boyska

您可能无法将ram使用量减少那么多。但是如果你使用mod_php, 您可能需要切换到mod_fcgid 相反

虽然mod\\u php稍微慢一些,但它甚至在不需要的时候加载php,例如提供图像、静态文件甚至缓存。如果你有很多请求,这就是很多ram。

使用fcgid将大大减少这种情况。

此外,使用静态缓存(如w3total缓存)将完全避免调用php,这是一个非常大的优势:ram使用更少,db连接更少。

SO网友:goldenapples

哈我现在正在开发一个web应用程序,因为我完全想让数据和使用量过载,超出我的共享托管帐户所能处理的范围,所以我决定-虽然在WP中构建非常容易-尝试从BackPress 作为一个框架,只构建我特定用例所需的内容。

因此,我能够将我的核心环境从WP中的数百个PHP文件减少到我实际需要的20个左右,同时仍然能够利用WordPress中我喜欢的所有db、HTTP、用户管理、格式化和cron功能。

问题是,这需要大量的工作,我永远不会相信我的黑客工作会超出我个人的使用范围。如果您想使用完整的WP环境,请按原样使用。它之所以如此出色,是因为数百名开发人员在几年内对其进行了微调。就像这里的每个人都说过的那样,通过找到更好的托管计划和研究缓存技术,您将比通过破解内核可能获得的结果更进一步。

SO网友:Ashfame

是的,WordPress首先加载所有内容,然后执行我们要求它执行的操作。我记得我们可以在RAM中创建一个虚拟池,在那里我们可以放入文件。我想把整个WordPress放在内存中(<;10MB)&;然后,我们可以节省大量的I/O,仅此一项就可以提高速度。但我从来没有机会尝试过,而且我也不太擅长追求这样的东西。但看起来值得一试。

SO网友:Ayaz Malik

一些基本建议:

用于缓存的w3 total cache插件

  • 安装并启用memcache,还可以从w3 total cache设置中启用(操作码缓存也是一个很好的选项,但它与w3 total cache插件不兼容)
  • 最小化对主题文件中直接链接的查询我经营着一个著名的wordpress网站,每天都有巨大的流量。。我甚至没有献身精神,为我做得很好:)

  • 结束

    相关推荐