2012-01-31 31 views
9

Tôi đang tạo một cửa hàng trực tuyến. Tôi gặp vấn đề về hiệu suất nếu tôi sử dụng chức năng xoay "render" thay vì "include".Twig: render vs include

Dưới đây là đoạn code mà sẽ hiển thị một danh mục sản phẩm:

Danh mục điều khiển:

<?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, 
     )); 
    } 
} 

... mẫu cho catalogue điều khiển:

{# 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 %} 

... điều khiển sản phẩm:

<?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); 
    } 
} 

... đơn giản (nhưng phức tạp hơn trong tương lai) mẫu cho bộ điều khiển sản phẩm:

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

Vì vậy, nếu tôi sử dụng:

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

... tất cả ok: 147ms và bộ nhớ 4608Kb.

Nhưng khi tôi cần một bộ điều khiển để hiển thị các sản phẩm:

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

... kịch bản của tôi tiêu thụ quá nhiều thời gian và bộ nhớ: 3639ms và bộ nhớ 17664Kb!

Làm cách nào để tăng tốc độ và giảm mức tiêu thụ bộ nhớ bằng bộ điều khiển?

+6

Bạn có ở chế độ dev hoặc prod không? Sự khác biệt có thể gây ngạc nhiên. –

+2

Tôi đã sử dụng chế độ "dev". Khi tôi thử chế độ "prod", tôi đã rất ngạc nhiên - ứng dụng này rất nhanh. – George

+9

Dev thực hiện rất nhiều việc ghi nhật ký và có các bộ đệm quan trọng nhất bị vô hiệu hóa. Bạn nên cố gắng so sánh dev và prod với xdebug để xem các thay đổi đang diễn ra trong nội bộ.Nó có thể làm giảm sự thôi thúc để tối ưu hóa những thứ như vậy trong tương lai. –

Trả lời

4

Mỗi cuộc gọi hiển thị sinh ra một yêu cầu mới, với sự cố xuống cấp hiệu suất mà bạn mô tả. Tôi không nghĩ rằng có nhiều bạn có thể làm về điều đó, nhưng bằng cách sử dụng bộ nhớ đệm esi, để các mảnh duy nhất đến từ các cuộc gọi render có thể được lưu trữ. Nếu không, bạn có thể thử sửa đổi logic của mình để giảm mức sử dụng các cuộc gọi hiển thị.

+0

Nhưng nó vẫn đáng ngạc nhiên rằng một yêu cầu với 'include' mất 147ms/4.5MB và một yêu cầu sử dụng' render' một lần (và do đó cũng sinh ra chỉ một yêu cầu phụ không nên mất quá 147ms) chiếm 4000ms/17.5 MB. Chúng tôi có cùng một vấn đề trong một dự án ngay bây giờ nhưng với các vụ nổ sử dụng bộ nhớ như 150MB (~ 6 yêu cầu phụ). – flu

0

Sửa lỗi nếu tôi sai, nhưng ý tưởng cơ bản là bao gồm "sao chép bột nhão" về nội dung thay vì lệnh.

Trong khi lệnh kết xuất phải tạo bộ điều khiển trước, khởi tạo, chạy hàm tương ứng vv. Vậy ai biết pháo hạng nặng bị ẩn bên trong lớp của bộ điều khiển hoặc cha mẹ, nhà xây dựng và vv?

Cũng nên nhớ rằng thậm chí các mẫu được bao gồm đều được hiển thị. Vì vậy, bạn thậm chí có thể nhận được các cuộc khảo sát hoặc một cái gì đó tương tự khi dựng hình từ cành cây. Cá nhân tôi cố gắng tránh vẽ bất cứ điều gì bên ngoài sự trở lại của bộ điều khiển.

Cộng với như đã đề cập bởi Louis-Philippe Huberdeau trong nhận xét, môi trường dev có thể khác biệt đáng kể so với chế độ prod vì các tùy chọn và ghi nhật ký khác nhau.

Đối với lời khuyên - hãy thử tránh đặt logic trong bộ điều khiển của bạn hoặc thử sử dụng các đối tượng tĩnh thường được sử dụng trong bộ điều khiển để sử dụng lại chúng thay vì tạo mới nhiều lần. Và hiển thị nội dung từ bộ điều khiển chỉ