How to fix (and avoid!) Craft CMS performance issues

One of Craft's key features is it's flexibility, but that same feature can also make it easy to write poorly performing code. Here's how to avoid some common pitfalls.

Intro

  • Craft makes it easy to write poorly performing code

Common signs that you have a performance problem

  • 504 errors
  • Slow page loads

Common causes

  • Script executes for too long / reaches max execution time

What's causing this

Poorly designed / optimsied database queries

  • Easy to end up with in Craft if not careful because content modelling in the CP makes it easy to make relations

Commonly either

  • too many queries (e.g. nested loops / N+1)
  • Queries that are too complex to execute quickly

How to fix

Prevention is better than cure!

  • Understand how Craft models content (many things are a relation, = many joins)
  • Consider performance when modelling content

Too late, my site is already slow!

  • Fear not
  • Obvious answer is to throw either/both more server resources or caching at the problem
  • While this can offer a quick fix in a pinch, it's really masking the issue rather than fixing it
  • Caching should still be used to provide fastest possible UX (reference Upper here) but shouldn't be a crutch

Start with DB queries

  • Most common cause so good place to start

The steps:

// This would be nice a diagram

  • review -> profile -> target -> refactor -> profile again

How to profile your Twig templates

// Screenshots would be helpful here // Reference Mijingo video (OS's favourite :) )

  • Yii debug toolbar
  • Quick wins: -- Total query count -- total execution time

How to find refactoring targets your templates

  • Make a git branch for your refactoring and commit as you go - use the history to record your investigations as you go, and so you can step back if you make a mistake
  • Isolate the parts of your templates that run queries in turn (grep for craft.entries / craft.categories etc) to find the poorly performing parts
  • Change one thing at a time
  • Look out for common antipatterns

Common Craft templating performance antipatterns

Expand these with examples

  • Querying inside (nested) loops: -- N+1 problem -- can often be hidden by include / and other attempts to make templates DRY

  • Too much logic in twig templates: not a performance issue in and of itself (as Twig compiles down to PHP) but makes performance issues easier to create and harder to spot - consider moving heavy lifting logic to PHP via a custom module

  • Populating Elements when you don't need them -- Use ids instead of all where possible when feeding results of one query into another

Approaches for fixing them

  • Eager loading a double-edged sword: can be very helpful but not a magic bullet
  • // @tom ususally the approach here would lazy loading (first unlucky user, let's discuss) — ƒ
  • Simplify content model ()
  • // @todo expand here

If you can't fix, mitigate

  • Sometimes even there are queries that can't be simplified
  • Move expensive queries to async / xhr
  • If all else fails apply caching (link out rather than go into detail about options here)

Further reading

Debugging / profiling

Caching

Optimising database queries

Share & discuss this: