web-dev-qa-db-ja.com

小枝:レンダリングとインクルード

オンラインストアを作成しています。 「include」の代わりにtwig function "render"を使用すると、パフォーマンスの問題が発生します。

製品カタログを表示するコードは次のとおりです。

カタログコントローラー:

<?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 } %}

...すべてOK:147msおよび4608Kbメモリ。

しかし、製品を表示するためにコントローラーが必要な場合:

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

...私のスクリプトは時間とメモリを消費しすぎます:3639msと17664Kbのメモリ!

コントローラを使用して速度を上げ、メモリ消費を減らすにはどうすればよいですか?

9
George

レンダリング呼び出しごとに、説明しているパフォーマンス低下の問題を伴う新しいリクエストが生成されます。それについてできることはあまりないと思いますが、esiキャッシングを使用して、レンダー呼び出しからの単一フラグメントをキャッシュできるようにします。それ以外の場合は、ロジックを修正して、レンダー呼び出しの使用量を減らすことができます。

4

私が間違っている場合は訂正してください。ただし、基本的な考え方は、コマンドの代わりにコンテンツを基本的に「コピーアンドペースト」することです。

レンダリングコマンドは最初にコントローラーを作成し、初期化し、対応する関数を実行する必要があります。では、このコントローラーまたは親のクラス、コンストラクターなどの中に隠されている重砲を誰が知っているでしょうか。

また、含まれているテンプレートもレンダリングされることを忘れないでください。そのため、小枝からレンダリングすると、再帰などが発生する可能性があります。個人的には、コントローラーのリターン以外のものをレンダリングしないようにしています。

さらに、Louis-Philippe Huberdeauがコメントで述べているように、開発環境は、オプションとログが異なるため、本番モードとは大幅に異なる可能性があります。

アドバイスについては、コントローラーにロジックを配置しないようにするか、コントローラーで頻繁に使用される静的オブジェクトを使用して、新しいオブジェクトを何度も作成するのではなく、それらを再利用してみてください。そして、コントローラーからのみレンダリングします

0
GodlyHedgehog