如何加速Symfony2模板渲染?

14
我有一个Symfony2应用程序,渲染约6000个数据库实体。
我优化了ORM(propel)查询,现在数据库请求非常快。剩下的是Symfony控制器和Twig模板呈现引擎。
有没有一种方法可以加速呈现(例如切换到php模板?) 我能否获得比Symfony profiler更详细的分析信息?
以下是Profiler数据的摘录。
这张图片显示了占用95%计算时间的分支,大约为2.8秒。 数据库检索需要~0.5秒,呈现需要~1秒,格式化需要最长时间,约为1.5秒。
我不确定包含PHP类的文件长度会产生什么影响,但是Propel生成了很多代码(我的最复杂的实体基类几乎有10k行代码),因此这可能也会减慢对象创建的速度。
我认为使用数组格式化程序(从而绕过对象创建步骤)将是一种解决方案,但这有点违背了ORM的目的。

真正的解决方案:不要渲染6000个条目。 但是:你尝试过Propel2吗?(https://github.com/propelorm/Propel2/issues/478#issuecomment-28193826) - Marc J. Schmidt
6个回答

9
在生产模式下,Symfony2的Twig模板渲染实际上是使用缓存模板完成的,这意味着它是一个PHP模板;一个Twig模板编译成纯PHP代码。当然,在开发模式下,它不会像那样缓存模板,而是每次都进行编译。想了解更多信息,请在文档中查看

当页面数据量很大时,即使模板只是通常表现最快的普通PHP-HTML注入代码,PHP也需要一些时间来编译页面。 - 如果此页面不必每次从数据库中呈现,则可以考虑使用正常的HTTP缓存,如Varnish

至于分析。像XDebug这样的工具应该会为您提供比Symfony2内置的更详细的分析信息。


首先尝试使用XDebug比安装Xhprof更容易,感谢这个提示。另外,我希望在生产模式下,Twig模板能够编译成PHP文件,感谢您的确认。 - cw'

8

迭代6K次是很多工作量。

想法 #1:

你能实现数据分页吗?这似乎非常合理...

想法 #2(厚客户端):

实现一些JavaScript模板机制。然后,你的控制器应该返回JSON,以便JS完全渲染它。

即使在这种情况下,依靠浏览器快速完成6K次循环也是很困难的。你需要在之间实现暂停(例如,在每150次迭代之后),以便浏览器不会进入无响应状态...


5
看起来您需要使用PHP twig扩展程序,它是针对您的情况而制作的。
从文档中可以得知:
Twig现在将自动编译您的模板以利用C扩展程序。请注意,此扩展程序不会替换PHP代码,而只提供了Twig_Template :: getAttribute()方法的优化版本。
就我个人而言,当我一年前尝试用它进行项目时,几乎没有任何显著的影响。如果您使用它,请分享您的经验。

我对XDebug分析器进行了一些实验,但似乎Twig_Template::getAttribute不是瓶颈所在。如果有时间的话,我将分享我的经验。 - cw'
请注意,这是针对Twig 1.x的。Fabien没有将其移植到Twig 2,因为它并没有带来太多改进。https://github.com/twigphp/Twig/pull/2310 - scipilot

2

您在这里提出了两个问题:

1)如何加速模板渲染?

分析器表明查询是通过渲染进行的,我认为您可能忘记了一个连接,最好在渲染之前执行一个大查询(可能可缓存),并在视图层中只使用查询结果。

2)如何获得更详细的分析数据?

我建议安装xhprof进行高级分析,您可以使用这个很棒的bundle:https://github.com/jonaswouters/XhprofBundle。Xhprof跟踪php调用并构建时间执行统计和可视化调用图。我使用它来检测哪些进程结果需要存储在缓存中。


1

我在redis中缓存了视图。

渲染视图时,Twig会通过查询获取数据,等待查询需要一些时间。因此,快速显示的方法是不进行查询。在我的项目中,当某个地方不经常更改时,我使用控制器中的renderView函数缓存该部分的html代码。


0

在@jperovic的答案基础上进行扩展:

像他所说的,您可以创建一个API来抛出JSON数据,并将工作放在客户端。此外,也许您不需要一次显示所有6000个实体?因此,通过ajax调用延迟加载其他数据可能会有所帮助。

在数据库方面,缓存结果并定期打破缓存以查看是否有任何新数据。或者,如果数据需要始终保持最新状态:无论应用程序的哪个部分更新数据,都将发送请求告诉您的API它应该打破缓存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接