Zweig: render vs enthalten
Erstelle ich einen online-Shop.
Ich habe ein performance-problem, wenn ich den Zweig mit der Funktion "Rendern" anstatt "include".
Hier ist der code, der zeigt, dass ein Produkt-Katalog:
Katalog-controller:
<?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,
));
}
}
... Vorlage für Katalog-controller:
{# 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 %}
... Produkt-controller:
<?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);
}
}
... einfach (aber komplizierter in der Zukunft) - Vorlage für die Produkt-controller:
{# src/Acme/StoreBundle/Resources/views/Product/show.html.twig #}
{{ product.name }}
So, wenn ich:
{% include "StoreBundle:Product:show.html.twig" with { product: product } %}
...alles ok: 147ms und 4608Kb Speicher.
Aber wenn ich einen controller um das Produkt anzuzeigen:
{% render "StoreBundle:Product:show" with { product: product } %#}
...mein script verbraucht zu viel Zeit und Speicher: 3639ms und 17664Kb Speicher!!!
Wie die Erhöhung der Geschwindigkeit und der Speicherverbrauch durch die Verwendung des Controllers?
- Sind Sie im dev oder prod-Modus? Der Unterschied ist überraschend.
- Ich habe die "dev" - Modus. Als ich versuchte, "prod" - Modus, ich war überrascht - der Antrag war sehr schnell.
- Dev hat eine Menge von Protokoll-und hat die wichtigsten caches deaktiviert. Sie sollten versuchen, zu vergleichen dev und prod mit xdebug, um zu sehen, die Art von Veränderungen, intern. Es kann reduzieren den Drang zu optimieren solche Dinge in der Zukunft.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Pro render-Aufruf erzeugt einen neuen Antrag, mit den Leistungseinbußen Problem, das Sie beschreiben. Ich glaube nicht, dass es viel Sie tun können, dass aber mit esi-caching, so dass die einzelnen Fragmente aus render-Aufrufe zwischengespeichert werden können. Ansonsten könnte man versuchen zu überarbeiten, Sie Ihre Logik, um reduzieren Sie die Verwendung von render-Aufrufe.
include
nimmt 147ms/4.5 MB und eine Anfrage, die verwendetrender
einmal (und damit auch laicht nur ein sub-request, der sollte nicht mehr als 147ms) dauert bis 4000ms/17.5 MB. Wir haben das gleiche problem in einem Projekt jetzt aber mit der Speichernutzung Explosionen wie 150 MB (~6 unteranfragen).Mich korrigieren, wenn ich falsch bin, aber die grundlegende Idee ist, dass gehören im Grunde "copy-Pasten" Inhalt anstatt den Befehl.
In der Erwägung, dass render-Befehl erstellen müssen Sie den controller zuerst initialisieren, führen Sie die entsprechende Funktion etc. Wer weiß, was schwere Artillerie im inneren verborgen ist dieser controller der Eltern oder Klassen, Konstruktoren und so weiter?
Denken Sie auch daran, dass sogar die mitgelieferten templates gerendert werden. So dass Sie sogar rekursionen oder etwas ähnliches, wenn das Rendern von Zweig. Ich persönlich versuche zu vermeiden rendering etwas außerhalb des Controllers zurück.
Plus wie erwähnt von Louis-Philippe Huberdeau in den Kommentaren, dev-Umgebung kann sich drastisch unterscheiden sich von prod-Modus aufgrund der unterschiedlichen Optionen und Protokollierung.
Als für die Ratschläge - versuchen Sie verhindern, dass die Logik in den Controllern, oder versuchen Sie es mit statischen Objekten, die Häufig in Controllern wiederzuverwenden, statt neue zu erstellen über und über. Und render-Zeug vom Controller nur