Twig:渲染vs包含

时间:2012-01-31 09:21:17

标签: symfony twig

我正在创建一个在线商店。 如果我使用twig函数“render”而不是“include”,我会遇到性能问题。

以下是显示产品目录的代码:

目录控制器:

<?php
// src/Acme/StoreBundle/Controller/Product/Catalog.php

namespace Acme\StoreBundle\Controller\Product;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class CatalogController extends Controller
{
    /**
     * @Template()
     */
    public function productAction(\Acme\StoreBundle\Entity\Product\Category $category)
    {
        $qb = $this->getDoctrine()
            ->getRepository('StoreBundle:Product')
            ->createQueryBuilder('product')
            ->select('partial product.{id, token, name}')
            ->innerJoin('product.categoryRelation', 'categoryRelation')
            ->where('categoryRelation.category = :category_id');

        $qb->setParameters(array(
            'category_id'  => $category->getId(),
        ));

        $products = $qb->getQuery()
            ->getResult();

        return $this->render('StoreBundle:Product\Catalog:product.html.twig', array(
            'category' => $category,
            'products' => $products,
        ));
    }
}

...目录控制器的模板:

{# src/Acme/StoreBundle/Resources/views/Product/Catalog/product.html.twig #}
{% extends 'AcmeDemoBundle::layout.html.twig' %}

{% block content %}
    <h1>{{ category.name }}</h1>

    <ul>
    {% for product in products %}
        <li>
            {#% render "StoreBundle:Product:show" with { product: product } %#}
            {% include "StoreBundle:Product:show.html.twig" with { product: product } %}
        </li>
    {% endfor %}
    </ul>

{% endblock %}

......产品控制员:

<?php
// src/Acme/StoreBundle/Controller/Product.php

namespace Acme\Enter\StoreBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

use Enter\StoreBundle\Entity\Product;

class ProductController extends Controller
{
    /**
     * @Template()
     */
    public function showAction(Product $product)
    {
        return array('product' => $product);
    }
}

...产品控制器的简单(但将来会更复杂)模板:

{# src/Acme/StoreBundle/Resources/views/Product/show.html.twig #}
{{ product.name }}

所以,如果我使用:

{% include "StoreBundle:Product:show.html.twig" with { product: product } %}

...一切正常:147ms和4608Kb内存。

但是当我需要一个控制器来显示产品时:

{% render "StoreBundle:Product:show" with { product: product } %#}

...我的脚本消耗太多时间和内存:3639ms和17664Kb内存!

如何使用控制器来提高速度并减少内存消耗?

2 个答案:

答案 0 :(得分:4)

每个渲染调用都会产生一个新请求,其中包含您正在描述的性能下降问题。我不认为你可以做多少但是使用esi缓存,这样可以缓存来自渲染调用的单个片段。否则,您可以尝试修改逻辑以减少渲染调用的使用。

答案 1 :(得分:0)

如果我错了,请纠正我,但基本的想法是基本上包括&#34; copy-paste&#34;它的内容而不是命令。

而渲染命令必须首先创建控制器,初始化它,运行相应的功能等。那么谁知道在这个控制器或父类的类,构造器等中隐藏了什么重炮?

还要记住,甚至包含的模板都会被渲染。所以你甚至可以从twig渲染时得到递归或类似的东西。我个人试着避免在控制器的返回之外渲染任何东西。

正如Louis-Philippe Huberdeau在评论中提到的那样,由于不同的选项和日志记录,开发环境可能与产品模式截然不同。

至于建议 - 尝试避免在控制器中放置逻辑,或尝试使用控制器中经常使用的静态对象来重用它们,而不是一遍又一遍地创建新的。并仅从控制器渲染内容