如何加速Symfony2中的模板渲染?

时间:2013-12-05 13:03:54

标签: php performance symfony twig

我有一个symfony2应用程序,它可以渲染大约6000个数据库实体。

我优化了ORM(推进)查询,现在数据库请求非常快。剩下的就是symfony控制器和twig模板渲染引擎。

有没有办法加快渲染速度(例如切换到php模板?) 我可以获得比symfony profiler更详细的分析信息吗?

以下是剖析器数据的摘录。

symfony profiler screenshot

编辑:我使用xDebug分析了我的代码,发现生成对象非常昂贵。从PropelObjectFormater->getAllObjectsFromRow中的数据库行创建数千个PHP对象需要花费大部分时间。

profiler_run_excerpt

图像显示的分支占用了95%的计算时间,约为2.8秒。 数据库检索需要约0.5秒,渲染时间约为1秒,格式化时间最长约为1.5秒。

我不确定包含PHP类的文件的长度会有什么影响,但是Propel生成很多代码(我最复杂的实体基类有近10k行代码)所以这也可能减慢对象的创建速度。

我认为使用数组格式化程序(因此绕过对象创建步骤)将是一种解决方案,但这有点违背了ORM的目的。

6 个答案:

答案 0 :(得分:9)

在生产模式下,Symfony2的Twig模板渲染实际上是使用缓存模板完成的,这意味着 是一个PHP模板;一个Twig模板编译成纯PHP代码。在开发模式下,它当然不会像这样缓存模板,而是每次都编译它。阅读更多相关信息here, in the docs

PHP需要花费一些时间来编译包含那么多数据的页面,即使模板只是普通的PHP-HTML输入代码,往往性能最快。 - 您可能希望查看正常的HTTP缓存,例如Varnish,如果此页面每次都不必从数据库中呈现

至于剖析。像XDebug这样的东西可以让你获得比Symfony2内置的更详细的分析信息。

答案 1 :(得分:8)

6K的迭代是很多工作。

想法#1:

您可以实施数据分页吗?这似乎非常合理......

创意#2(胖客户端):

实施一些JavaScript模板机制。然后,您的控制器应返回JSON,以便JS通过它并完全呈现它。

即使在这种情况下,依靠浏览器的速度快速做6K循环也是很多问题。您需要在两者之间实现暂停(例如,在每第150次迭代之后),因此浏览器不会进入非响应模式...

答案 2 :(得分:5)

听起来您需要使用PHP twig extension,这是根据您的情况制作的。

来自docs:

  

从现在开始,Twig会自动将模板编译为   利用C扩展。请注意,此扩展名不会   替换PHP代码,但只提供优化版本的   Twig_Template :: getAttribute()方法。

当我一年前为我的项目尝试时,我个人并没有得到任何明显的影响。如果您使用它,请分享您的经验。

答案 3 :(得分:2)

你在这里问两个问题:

1)如何加速模板渲染?

探查器告知查询被渲染投掷渲染,我认为你忘记了一个连接,最好在渲染之前执行一个大的查询(可能是可缓存的),并且只在视图层中使用查询结果。

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

我建议安装xhprof进行advenced profiling,你可以使用这个很棒的包:https://github.com/jonaswouters/XhprofBundle。 Xhprof跟踪php调用并构建时间执行统计和可视化调用图。我用它来检测我必须存储在缓存中的进程结果。

答案 4 :(得分:1)

我在redis中缓存了视图。

渲染视图时,Twig将通过查询获取数据,等待查询需要一些时间。所以快速显示方式永远不会查询。在我的项目中,当某个地方没有改变时,我通过使用控制器中的renderView函数来缓存该部分的html代码。

答案 5 :(得分:0)

建立在@jperovic回答:

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

在数据库端,缓存结果并经常中断缓存以查看是否有任何新数据。或者,如果数据需要始终保持最新:无论应用程序更新哪一部分,数据都会发送一个请求,告知您的API应该破坏缓存。