Component Library and Twig Include Performance
A theme has grown to 140 Twig templates. Many paragraphs render the same card component via {% include 'card.html.twig' with {...} %} inside a loop over 30 items per page. Profiling shows template rendering is a top cost. The card template uses {% if %} chains and calls {{ content.field_image }} plus a custom {{ my_component_data }} variable set in preprocess. The team wants to reduce render time and keep the component reusable across node and paragraph templates. Caching is enabled. They also notice the card markup differs slightly between two node types, handled by conditionals inside the card.
1. Recommend structural changes to the component to improve performance and reusability.
Read the worked answer
Reasoning points:
{% include %}re-parses and re-executes the template each iteration. For a component included many times, use{% embed %}only when you need to override blocks; otherwise keep a single include but move branching out of the hot loop.- The
{% if %}chains inside the card that depend on node type should be resolved by the caller (or by passing a variant variable) so the component has fewer runtime branches. This also fixes the two-node-type divergence cleanly. - Precompute
my_component_datain preprocess once per paragraph, not per include, and pass it as a simple variable. - Keep
content.*render arrays intact so Drupal's render cache can cache each field independently; don't convert them to strings.
Recommended: a single card.html.twig with a variant variable and no node-type conditionals; callers pass variant. Use {% include ... only %} to limit context and avoid leaking variables.
2. How would you verify the change actually improved performance without breaking caching?
Read the worked answer
Verification:
- Compare render time before/after with the render cache warm, since cold-cache numbers mislead. Use a profiler or timing around the paragraph render.
- Confirm cacheability: each card's render array should carry cache tags from the fields it renders. If preprocess builds
my_component_datafrom node data, add the node's cache tags/contexts so the component varies correctly. - Test with 30 items and confirm the number of template executions and query count do not regress.
- Check that
onlydid not drop needed variables, which would cause silent empty output rather than an error.
Reasoning: performance wins must be measured warm and must not trade correctness (cache invalidation) for speed.