Component Layout with Matrix Fields in Craft CMS: Configuration Guide
Developers often encounter pitfalls with Matrix Field in Craft CMS: either N+1 queries kill the server, or editors ask for 'one more block type'. In one project, a client's 'About' page had 25 blocks, each with an image. Page load took 8 seconds due to 25 separate media queries. After properly configuring eager loading, the time dropped to 1.2 seconds — a 6.7x improvement. With over 50 Craft projects, we've refined an approach where Matrix neither slows down nor frustrates the team.
How to Design Blocks to Avoid Redesigns
In a typical corporate site, the pageBody field contains 6–10 block types. Each block is a micro-structure: text, image, link, quote, code, stats. It's critical to plan the set of fields — adding a field later is harder than removing one. The optimal landing page structure:
pageBody (Matrix) ├── hero │ ├── heading, subheading, backgroundImage, ctaButton ├── richTextContent │ └── content (Redactor) ├── imageWithCaption │ ├── image, caption, alignment ├── twoColumns │ ├── leftContent, rightContent (Redactor) ├── testimonial │ ├── quote, author, role, avatar ├── stats │ └── items (Table field) ├── ctaBanner │ ├── heading, text, buttonLabel, buttonUrl └── codeSnippet ├── language, code Use Table fields for lists (stats, pricing) — they are faster than nested Matrix and easier to cache.
Twig Rendering: switch vs include vs component
Most projects use {% switch %} inside a loop — reliable and readable. But with 10+ blocks, the template becomes bulky. An alternative is to extract each block into a separate include. This simplifies maintenance but is marginally slower due to multiple include calls. The optimal approach renders blocks via a component approach with fragment caching.
| Approach | Speed | Maintainability | Caching |
|---|---|---|---|
| switch | high | low (bulky) | easy to cache whole |
| include | medium | high | each template cached separately |
| components | high | high | fragment caching |
In our experience, pages with 15+ blocks gain 40–50 ms by including cache tags.
Why N+1 Destroys Performance and How to Avoid It
Without eager loading, each block with an Assets field generates a separate query. For example, an image block searches for the image, a testimonial block for the avatar. If the page has 10 blocks, you get 10 DB queries plus the block list query. The solution is a single with() call: {% set blocks = entry.pageBody.with(['image', 'avatar', 'backgroundImage']).all() %}.
For blocks containing nested Matrix (e.g., tabs with inner content), use .with()['subMatrixField.childField'] — Craft supports deep eager loading. Full details in the official Craft CMS documentation.
What to Do If Matrix Slows the Control Panel
A Matrix with 50+ blocks in CP is a common nightmare. The reason: each block renders its fields. The solution is to fragment the matrix into multiple fields: separate Matrix for 'header', 'body', and 'footer'. Alternatively, use Neo Field by McDowell — an analog supporting nesting, though at $99 cost.
Tool Selection: When to Use Matrix, Neo, Table
| Criterion | Matrix (built-in) | Neo (plugin) | Table Field | SuperTable (plugin) |
|---|---|---|---|---|
| Block types | Any, static | Any, nested | Single row type | Single type, flexible fields |
| CP performance | Medium (20+ blocks) | Worse (more complex) | Excellent | Good |
| Nesting | Only 1 level (via Table) | Multi-level | None | 1 level |
| Cost | Free | $99 | Free | $59 |
| Suitable for | Page builder with 5–10 blocks | Complex structures (atomic design) | Tables, price lists | Lists with varying fields |
Matrix is best for 80% of projects. Neo is worth it only for more than two levels of nesting. Table and SuperTable are for tabular data.
Block Caching Strategies for Matrix
Matrix blocks break page caching without a strategy. The solution is to cache each block separately with tags. In Twig:
{% cache globally using key 'block-' ~ block.id tags 'matrixBlock:' ~ block.id %} {% include 'matrix/_' ~ block.type.handle %} {% endcache %} When a block is modified, Craft invalidates only its cache. For static blocks (richText), cache for a day; for media, for an hour.
Example pageBody structure for quick start
pageBody (Matrix): - hero (heading, subheading, backgroundImage, ctaButton) - richTextContent (content Redactor) - imageWithCaption (image, caption, alignment) - twoColumns (leftContent, rightContent Redactor) - testimonial (quote, author, role, avatar) - stats (items Table field) - ctaBanner (heading, text, buttonLabel, buttonUrl) - codeSnippet (language, code) This set covers 90% of typical pages.
What You Get from Proper Matrix Configuration
After completion, you receive:
- A configured Matrix Field with 5–8 block types.
- Twig templates supporting responsive layouts (mobile version determined via
craft.app.request.isMobileif needed). - Eager loading configured for all relational fields (Assets, Categories, Entries).
- Documentation on adding new blocks and editor training (1 hour).
- Performance guarantee: page load with 10 blocks under 1.5 seconds.
Common Mistakes and Solutions
| Mistake | Solution |
|---|---|
| Using Matrix for simple lists | Use Channel or Table |
| Forgetting eager loading for images | Add .with() for all relations |
| Too many block types (over 10) | Limit to 5–8, move rare blocks to a separate field |
Not setting maxBlocks |
Set a limit (e.g., 20) |
| No fragment caching | Wrap each block in {% cache %} with a tag |
When to Avoid Matrix
Matrix is inconvenient for:
- Sites with one content type (blog) — Rich Text suffices.
- Sites with a rigid grid (e.g., portfolio) — better structured via Entry Type.
- High-load projects (millions of blocks) — Matrix scales poorly; consider Headless CMS or custom solutions.
Otherwise, it is the standard Craft CMS tool, used in 90% of our projects. Our team has 5+ years and 50+ Craft projects, ensuring optimal Matrix configuration. To speed up your project, get a free consultation.
Configuring a Matrix with 5–8 block types and templates takes 2–4 days. Cost depends on the number of types and design complexity, determined after analysis.







