Rendering the comment form for authenticated users happens via #post_render_cache
, because the form is personalized for the current user. But, to build the comment form, we need a comment entity. And to build a comment entity, we must use ::create()
, which will call ::applyDefaultValues()
, which is expensive because of all the Typed Data things (IIRC) it needs in order to function.
public function renderForm(array $element, array $context) {
$field_name = $context['field_name'];
$entity = $this->entityManager->getStorage($context['entity_type'])->load($context['entity_id']);
$field_storage = FieldStorageConfig::loadByName($entity->getEntityTypeId(), $field_name);
$values = array(
'entity_type' => $entity->getEntityTypeId(),
'entity_id' => $entity->id(),
'field_name' => $field_name,
'comment_type' => $field_storage->getSetting('bundle'),
'pid' => NULL,
);
$comment = $this->entityManager->getStorage('comment')->create($values);
$form = $this->entityFormBuilder->getForm($comment);
$markup = $this->renderer->render($form);
$callback = 'comment.post_render_cache:renderForm';
$placeholder = $this->generatePlaceholder($callback, $context);
$element['#markup'] = str_replace($placeholder, $markup, $element['#markup']);
$element = $this->renderer->mergeBubbleableMetadata($element, $form);
return $element;
}
Applying the same trick as in #2458817: Creating new user entities for anonymous users is very slow is impossible, because it's very likely for comment entities to have additional fields, and because we are showing a form, we need those default values to be applied (so that their widgets have the expected default values)!
Comment | File | Size | Author |
---|---|---|---|
#2 | 2471218.patch | 2.44 KB | amateescu |
Comments
Comment #1
Wim Leers@fago, @Berdir, did we have an idea on how to solve this?
Comment #2
amateescu CreditAttribution: amateescu for Drupal Association commentedDiscussed this a bit a few days ago with @Berdir and we simply need a full content entity in order to generate a form for it.
So all we can do here is optimize
CommentPostRenderCache::renderForm()
to not do any processing that's already done byCommentDefaultFormatter::viewElements
.1 cut down, 999 to go :)
Comment #3
Wim LeersYay!
Look at that, I guess we forgot that… or was it newly added at a later time perhaps?
In any case: thanks!
This looks beautifully simple!
Comment #4
xjmThis makes sense. Committed and pushed to 8.0.x. Thanks!
Comment #6
Wim LeersThis saved 2 milliseconds on
/node/1
:)Comment #7
Fabianx CreditAttribution: Fabianx for Acquia commentedSo it does not make sense to create cached default values for such entities? Provided the TypedData things can be cached somehow?
Comment #8
andypost@Fabianx seems yes, comment render/caching needs separate issue
There's already
#2002094: Improve performance of comment.html.twig
#1857946: Comment parent template variables are built twice