title: How-to: Optimize Symfony's forms' performance?
body: <p>I have a form that is the bottleneck of my ajax-request.</p>
  
  <pre><code>    $order = $this-&gt;getDoctrine()
          -&gt;getRepository('AcmeMyBundle:Order')
          -&gt;find($id);
      $order = $order ? $order : new Order();
  
      $form = $this-&gt;createForm(new OrderType(), $order);
  
      $formView = $form-&gt;createView();
  
      return $this-&gt;render(
          'AcmeMyBundle:Ajax:order_edit.html.twig',
          array(
              'form' =&gt; $formView,
          )
      );
  </code></pre>
  
  <p>For more cleaner code I deleted <code>stopwatch</code> statements.</p>
  
  <p>My <strong>OrderType</strong> has next fields:</p>
  
  <pre><code>    $builder
          -&gt;add('status') // enum (string)
          -&gt;add('paid_status') // enum (string)
          -&gt;add('purchases_price') // int
          -&gt;add('discount_price') // int
          -&gt;add('delivery_price') // int
          -&gt;add('delivery_real_price', null, array('required' =&gt; false)) // int
          -&gt;add('buyer_name') // string
          -&gt;add('buyer_phone') // string
          -&gt;add('buyer_email') // string
          -&gt;add('buyer_address') // string
          -&gt;add('comment') // string
          -&gt;add('manager_comment') // string
          -&gt;add('delivery_type') // enum (string)
          -&gt;add('delivery_track_id') // string
          -&gt;add('payment_method') // enum (string)
          -&gt;add('payment_id') // string
          -&gt;add('reward') // int
          -&gt;add('reward_status') // enum (string)
          -&gt;add('container') // string
          -&gt;add('partner') // Entity: User
          -&gt;add('website', 'website') // Entity: Website
          -&gt;add('products', 'collection', array( // Entity: Purchase
              'type' =&gt; 'purchase',
              'allow_add' =&gt; true,
              'allow_delete' =&gt; true,
              'by_reference' =&gt; false,
              'property_path' =&gt; 'purchases',
              'error_bubbling' =&gt; false,
          ));
  </code></pre>
  
  <p><strong>Purchase type</strong>:</p>
  
  <pre><code>    $builder
          -&gt;add('amount')
          -&gt;add('price')
          -&gt;add('code', 'variant', array(
              'property_path' =&gt; 'variantEntity',
              'data_class' =&gt; '\Acme\MyBundle\Entity\Simpla\Variant'
          ))
      ;
  </code></pre>
  
  <p>Also <strong>Purchase type</strong> has a listener that is not significant here. It is represented in Symfony profiler below as <code>variant_retrieve</code>, <code>purchase_form_creating</code>. You can see that it takes about 200ms.</p>
  
  <p>Here I put the result of profilers:
  <img src="https://i.stack.imgur.com/BzuEs.png" alt="SymfonyProfiler">
  <img src="https://i.stack.imgur.com/Yqk4k.png" alt="BlackFire Profiler">
  <img src="https://i.stack.imgur.com/wVIyn.png" alt="BlackFire Profiler"></p>
  
  <p>As you can see: <code>$this-&gt;createForm(...)</code> takes 1011ms, <code>$form-&gt;createView();</code> takes 2876ms and form rendering in twig is also very slow: 4335ms. As stated by blackfire profiler all the deal in <code>ObjectHydrator::gatherRowData()</code> and <code>UnitOfWork::createEntity()</code>.</p>
  
  <p>Method <code>createEntity()</code> called 2223 times because there is some field that mapped with <code>Variant</code> entity and has form type <code>Entity</code>. But as you can see from above code there is no <code>entity</code> types for variant. My <code>VariantType</code> is simple extended <code>text</code> form type that has <code>modelTransformer</code>. To not mess up everything you can see code for similar Type class at <a href="http://symfony.com/doc/current/cookbook/form/data_transformers.html#using-transformers-in-a-custom-field-type" rel="noreferrer">docs</a>.</p>
  
  <p>I found with XDebug that <code>buildView</code> for <code>VariantType</code> has been called in <code>Purchase</code>'s <code>buildView</code> with <code>text</code> form type. But after that from somewhere <code>buildView</code> for <code>VariantType</code> was called again and in this case it has <code>entity</code> form type. How can it be possible? I tried to define empty array in  <code>choices</code> and <code>preferred_choices</code> on every my form type but it didn't change anything. What I need to do to prevent <code>EntityChoiceList</code> to be loaded for my form?</p>