我的表单是我的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
。你可以看到大约需要200ms。
这里我把分析器的结果:
正如您所看到的那样:$this->createForm(...)
需要1011毫秒,$form->createView();
需要2876毫秒,并且在树枝中渲染表格也非常慢:4335毫秒。正如blackfire profiler所述,所有交易都在ObjectHydrator::gatherRowData()
和UnitOfWork::createEntity()
。
方法createEntity()
调用2223次,因为有一些字段与Variant
实体映射并且表单类型为Entity
。但是从上面的代码可以看出,变体没有entity
种类型。我的VariantType
是具有text
的简单扩展modelTransformer
表单类型。为了不弄乱所有内容,您可以在docs看到类似Type类的代码。
我在XDebug中发现buildView
的{{1}} VariantType
已在Purchase
的{{1}} buildView
表单类型中调用。但是之后从text
buildView
再次调用了VariantType
,在这种情况下,它具有entity
表单类型。怎么可能?我尝试在choices
和preferred_choices
中为每个表单类型定义空数组,但它没有改变任何内容。我需要做些什么来防止为我的表单加载EntityChoiceList
?
答案 0 :(得分:2)
所描述的行为看起来像猜测者的工作。我觉得需要显示一些额外的代码(听众,VariantType
,WebsiteType
,PartnerType
)。
让我们假设某个类有variant
到Variant
和FormType
的关联,这个类的代码->add('variant')
没有明确的指定类型(正如我在那里看到的那样)是很多没有指定类型的地方)。然后DoctrineOrmTypeGuesser
进入游戏。
此代码将entity
类型(!)分配给此子级。调用EntityRepository::findAll()
并且DB的所有变体都是水合的。
至于其他表单优化方式:
答案 1 :(得分:0)
我对实体类型也有同样的问题,我需要列出城市,有像mire然后4000,我做的基本上是将选择注入表单。在您的控制器中,您从数据库中询问Variants,在存储库调用中,将它们水合为数组,并且只选择id和名称或标题,然后将其作为选项值传递到表单中。有了这个,数据库部分将更快。