У меня есть форма, которая является узким местом моего запроса ajax.
$order = $this->getDoctrine()
->getRepository('AcmeMyBundle:Order')
->find($id);
$order = $order ? $order : new Order();
$form = $this->createForm(new OrderType(), $order);
$formView = $form->createView();
return $this->render(
'AcmeMyBundle:Ajax:order_edit.html.twig',
array(
'form' => $formView,
)
);
Для более чистого кода я удалил операторы stopwatch
.
Мой OrderType имеет следующие поля:
$builder
->add('status') // enum (string)
->add('paid_status') // enum (string)
->add('purchases_price') // int
->add('discount_price') // int
->add('delivery_price') // int
->add('delivery_real_price', null, array('required' => false)) // int
->add('buyer_name') // string
->add('buyer_phone') // string
->add('buyer_email') // string
->add('buyer_address') // string
->add('comment') // string
->add('manager_comment') // string
->add('delivery_type') // enum (string)
->add('delivery_track_id') // string
->add('payment_method') // enum (string)
->add('payment_id') // string
->add('reward') // int
->add('reward_status') // enum (string)
->add('container') // string
->add('partner') // Entity: User
->add('website', 'website') // Entity: Website
->add('products', 'collection', array( // Entity: Purchase
'type' => 'purchase',
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'property_path' => 'purchases',
'error_bubbling' => false,
));
Тип покупки:
$builder
->add('amount')
->add('price')
->add('code', 'variant', array(
'property_path' => 'variantEntity',
'data_class' => '\Acme\MyBundle\Entity\Simpla\Variant'
))
;
Также Тип покупки имеет прослушиватель, который здесь не является существенным. Он представлен в профайле Symfony ниже variant_retrieve
, purchase_form_creating
. Вы можете видеть, что это занимает около 200 мс.
Здесь я поставил результат профилировщиков:
Как вы можете видеть: $this->createForm(...)
занимает 1011 мс, $form->createView();
занимает 2876 мс, а рендеринг формы в ветке тоже очень медленный: 4335мс. Как указано профилировщиком blackfire, все сделки заключаются в ObjectHydrator::gatherRowData()
и UnitOfWork::createEntity()
.
Метод createEntity()
называется 2223 раза, потому что есть некоторое поле, которое отображается с объектом Variant
и имеет тип формы Entity
. Но, как видно из вышеприведенного кода, для варианта нет типов Entity
. Мой VariantType
- это простой расширенный тип формы text
, который имеет modelTransformer
. Чтобы не испортить все, вы можете увидеть код для аналогичного класса типа docs.
Я нашел с XDebug, что buildView
для VariantType
был вызван в Purchase
buildView
с типом формы text
. Но после этого откуда-то buildView
для VariantType
был вызван снова, и в этом случае он имеет тип формы Entity
. Как это возможно? Я попытался определить пустой массив в choices
и preferred_choices
для каждого типа моей формы, но ничего не изменил. Что мне нужно сделать, чтобы предотвратить загрузку EntityChoiceList
для моей формы?